@calimero-network/mero-js 24.2.0 → 24.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1766,16 +1766,18 @@ var AdminApiClient = class {
1766
1766
  * Ask what this node can do for a member in `contextId`, before they sign
1767
1767
  * anything.
1768
1768
  *
1769
- * The two facts {@link performIntent} needs and a client cannot derive: whose
1770
- * account and key go in the warrant's `executor` and `executor_key`, and
1771
- * whether this node holds `CAN_AUTHOR_ON_BEHALF` on the owning group.
1769
+ * The facts {@link performIntent} needs and a client cannot derive: whose
1770
+ * account and key go in the warrant's `executor` and `executor_key`, which
1771
+ * release it pins, and whether this node holds `CAN_AUTHOR_ON_BEHALF` on the
1772
+ * owning group.
1772
1773
  * `canAuthorOnBehalf: false` comes back as an answer rather than an error, as
1773
1774
  * it is the default state of every context, so a caller can say "an admin of
1774
1775
  * `groupId` must grant it to `executorAccount`" instead of presenting a
1775
1776
  * warrant that will be refused after the author has spent a nonce on it.
1776
1777
  *
1777
- * `404` means the context belongs to no group, or this node holds no account
1778
- * yet; either way it can be named as no warrant's executor.
1778
+ * `404` means the context belongs to no group, this node holds no account or
1779
+ * identity in it yet, or its group names no release yet; no warrant can be
1780
+ * spent here until that changes.
1779
1781
  *
1780
1782
  * For a caller with no credential on the node at all — a browser tab holding
1781
1783
  * one signing key — use `RelayClient`, which reads this same route on a node
@@ -7472,7 +7474,7 @@ function splitVersion2(version) {
7472
7474
  var SIGN_DOMAIN2 = new TextEncoder().encode("calimero.warrant.v2");
7473
7475
  var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
7474
7476
  var MAX_CITED_HEADS = 64;
7475
- var UNPINNED_APP = "00".repeat(32);
7477
+ var MAX_RELEASE_VERSION_LEN = 256;
7476
7478
  async function intentHash(method, argsJson) {
7477
7479
  const args = new TextEncoder().encode(JSON.stringify(argsJson));
7478
7480
  return domainHash(INTENT_DOMAIN, [new TextEncoder().encode(method), args]);
@@ -7482,11 +7484,8 @@ async function signWarrant(input) {
7482
7484
  const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
7483
7485
  const executor = fromHex(input.executor, "executor", 32);
7484
7486
  const executorKey = fromHex(input.executorKey, "executorKey", 32);
7485
- const appVersion = fromHex(
7486
- input.appVersion ?? UNPINNED_APP,
7487
- "appVersion",
7488
- 32
7489
- );
7487
+ const releaseBytecodeId = fromHex(input.releaseBytecodeId, "releaseBytecodeId", 32);
7488
+ const releaseVersion2 = releaseVersionBytes(input.releaseVersion ?? "");
7490
7489
  const accountHeads = citedHeads(input.accountHeads, "accountHeads");
7491
7490
  const governanceFloor = citedHeads(input.governanceFloor, "governanceFloor");
7492
7491
  const signer = await resolveSigner(input.deviceSecret, input.signer, "deviceSecret");
@@ -7501,7 +7500,8 @@ async function signWarrant(input) {
7501
7500
  publicKey,
7502
7501
  executor,
7503
7502
  executorKey,
7504
- appVersion,
7503
+ releaseBytecodeId,
7504
+ releaseVersion2,
7505
7505
  method,
7506
7506
  commitment,
7507
7507
  u64le(accountHeads.length),
@@ -7519,7 +7519,9 @@ async function signWarrant(input) {
7519
7519
  publicKey,
7520
7520
  executor,
7521
7521
  executorKey,
7522
- appVersion,
7522
+ releaseBytecodeId,
7523
+ u32le(releaseVersion2.length),
7524
+ releaseVersion2,
7523
7525
  u32le(method.length),
7524
7526
  method,
7525
7527
  commitment,
@@ -7540,6 +7542,18 @@ function checkedSignature(signature) {
7540
7542
  }
7541
7543
  return signature;
7542
7544
  }
7545
+ function releaseVersionBytes(version) {
7546
+ const bytes = new TextEncoder().encode(version);
7547
+ checkReleaseVersionLength(bytes.length);
7548
+ return bytes;
7549
+ }
7550
+ function checkReleaseVersionLength(len) {
7551
+ if (len > MAX_RELEASE_VERSION_LEN) {
7552
+ throw new Error(
7553
+ `releaseVersion is ${len} bytes, over the ${MAX_RELEASE_VERSION_LEN} a node accepts`
7554
+ );
7555
+ }
7556
+ }
7543
7557
  function citedHeads(heads, label2) {
7544
7558
  const list = heads ?? [];
7545
7559
  if (list.length > MAX_CITED_HEADS) {
@@ -8177,7 +8191,6 @@ var RelayClient = class {
8177
8191
  "GET",
8178
8192
  `/admin-api/contexts/${encodeURIComponent(contextId)}/intents`
8179
8193
  );
8180
- this.checkedExecutor(body.data);
8181
8194
  return body.data;
8182
8195
  }
8183
8196
  /**
@@ -8188,7 +8201,13 @@ var RelayClient = class {
8188
8201
  * apply. Nothing accumulates and nothing is reusable.
8189
8202
  */
8190
8203
  async execute(contextId, method, argsJson = {}) {
8191
- const executor = this.executor ?? this.checkedExecutor(await this.describe(contextId));
8204
+ const described = await this.describe(contextId);
8205
+ const executor = this.checkedExecutor(described);
8206
+ const releaseBytecodeId = hex(
8207
+ fromHex(described.releaseBytecodeId ?? "", "the relay's releaseBytecodeId", 32)
8208
+ );
8209
+ const releaseVersion2 = described.releaseVersion ?? "";
8210
+ releaseVersionBytes(releaseVersion2);
8192
8211
  const signer = await this.authorSigner();
8193
8212
  const nonce2 = await this.config.nonces.next();
8194
8213
  const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
@@ -8197,6 +8216,8 @@ var RelayClient = class {
8197
8216
  authorAccount: this.config.authorAccount,
8198
8217
  executor: executor.executorAccount,
8199
8218
  executorKey: executor.executorKey,
8219
+ releaseBytecodeId,
8220
+ releaseVersion: releaseVersion2,
8200
8221
  method,
8201
8222
  argsJson,
8202
8223
  nonce: nonce2,
@@ -8207,10 +8228,7 @@ var RelayClient = class {
8207
8228
  "POST",
8208
8229
  `/admin-api/contexts/${encodeURIComponent(contextId)}/intents`,
8209
8230
  { method, argsJson, warrant, authorProof: this.config.authorProof }
8210
- ).catch((err) => {
8211
- if (err instanceof IntentRefusedError) this.executor = void 0;
8212
- throw err;
8213
- });
8231
+ );
8214
8232
  return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
8215
8233
  }
8216
8234
  /**
@@ -8456,7 +8474,7 @@ var RelayClient = class {
8456
8474
  return body.data;
8457
8475
  }
8458
8476
  /**
8459
- * The relay's answer, checked against a configured account and remembered.
8477
+ * The relay's answer, checked against a configured account.
8460
8478
  * Decoded here so a relay naming no key is refused before a nonce is taken.
8461
8479
  */
8462
8480
  checkedExecutor(answered) {
@@ -8470,7 +8488,6 @@ var RelayClient = class {
8470
8488
  `configured executorAccount ${configured} is not the relay's account ${executor.executorAccount}; a warrant naming it would be unspendable`
8471
8489
  );
8472
8490
  }
8473
- this.executor = executor;
8474
8491
  return executor;
8475
8492
  }
8476
8493
  /**