Create multi policyId without slot expiry

I want to create multi policyScript and policyId for user without timelock_expiry
If I create policy without pass timelock_expiry, it will generate the same policyId for same user

const scripts2 = CardanoWasm.NativeScripts.new();
const scriptPubKey = CardanoWasm.ScriptPubkey.new(baseAddress.payment_cred().to_keyhash());
const keyHashScript = CardanoWasm.NativeScript.new_script_pubkey(scriptPubKey);
scripts2.add(keyHashScript);
const policyScript = CardanoWasm.NativeScript.new_script_all(CardanoWasm.ScriptAll.new(scripts2));

Is there any way that I can create other policyId for same user without need to pass slot expiry

Since the policy ID is basically a hash of the contents in the policy script, it, of course, stays the same when nothing in the script changes.

You could use different keys.

Or you could introduce meaningless after constraints with slots in the past to artificially create policy scripts with differences.

I am not sure what you mean with " after constraints with slots in the past"
I only know to add time lock script like this

  const timelock = CardanoWasm.TimelockExpiry.new_timelockexpiry(
        CardanoWasm.BigNum.from_str((ttl + 999999999999).toString()),
      );
const timelockScript = CardanoWasm.NativeScript.new_timelock_expiry(timelock);

But + 999999999999 is not the wise way to set expire time for a policy

You can not only timelock so that a transaction may only be done before a certain slot. You can also timelock so that a transaction may only be done after a certain slot.

See: https://github.com/input-output-hk/cardano-node/blob/master/doc/reference/simple-scripts.md#time-locking

The corresponding class in cardano-serialization-lib is TimelockStart (instead of TimelockExpiry):
https://github.com/Emurgo/cardano-serialization-lib/blob/master/rust/pkg/cardano_serialization_lib.js.flow#L6976

I try with timelockStart but when mint nft with this policyScript, it return error transaction submit error ShelleyTxValidationError ShelleyBasedEraBabbage (ApplyTxError [UtxowFailure (FromAlonzoUtxowFail (WrappedShelleyEraFailure (ScriptWitnessNotValidatingUTXOW (fromList [ScriptHash \"16959a84b47c4638a02d4b6fb413873127ca0f056984945f979cb1ca\"]))))])

const timelockStart = CardanoWasm.TimelockStart.new(ttl - 10);
const timelockStartScript = CardanoWasm.NativeScript.new_timelock_start(timelockStart)
scripts2.add(timelockStartScript);

Beside that, how can I generate different keys to create script, currently I am using the current user wallet baseAddress.payment_cred().to_keyhash()

Two possibilities:

  1. I don’t know what your ttl is. It might be that ttl - 10 (10 seconds before the transaction becomes invalid) is still in the future. I would have chosen a value way in the past like the start of the current epoch (70156800) or something like that.
  2. If a script has a TimelockExpiry, the transaction has to have a set_ttl with a value less or equal than that expiry slot. Likewise if a script has a TimelockStart, the transaction has to have a set_validity_start_interval_bignum (https://github.com/Emurgo/cardano-serialization-lib/blob/master/rust/pkg/cardano_serialization_lib.js.flow#L7317) with a value greater or equal than that start slot.

As for the keys: Somewhere in your code, you are deriving that payment key from the seed phrase or from a master key. In the same way you can derive lots of other keys. But if you want to use them as the keys for a policy script, you will have to sign the transaction with those keys.

tks, the set_validity_start_interval_bignum works as I expect