@calimero-network/mero-js 24.1.3 → 24.2.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/account/create-context.d.ts +2 -4
- package/dist/account/create-context.js +34 -14
- package/dist/account/session.d.ts +3 -2
- package/dist/admin-api/admin-client.d.ts +6 -6
- package/dist/admin-api/admin-client.js +6 -6
- package/dist/admin-api/admin-types.d.ts +10 -11
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +84 -42
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +84 -42
- package/dist/index.mjs.map +2 -2
- package/dist/relay/index.d.ts +1 -1
- package/dist/relay/relay-client.d.ts +24 -27
- package/dist/relay/relay-client.js +39 -31
- package/dist/warrant/creation-warrant.d.ts +5 -1
- package/dist/warrant/creation-warrant.js +5 -1
- package/dist/warrant/governance-warrant.d.ts +5 -1
- package/dist/warrant/governance-warrant.js +5 -1
- package/dist/warrant/warrant.d.ts +7 -1
- package/dist/warrant/warrant.js +5 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1485,12 +1485,12 @@ var AdminApiClient = class {
|
|
|
1485
1485
|
* anything.
|
|
1486
1486
|
*
|
|
1487
1487
|
* The two facts {@link performIntent} needs and a client cannot derive: whose
|
|
1488
|
-
* account
|
|
1489
|
-
* `CAN_AUTHOR_ON_BEHALF` on the owning group.
|
|
1490
|
-
* back as an answer rather than an error
|
|
1491
|
-
* context
|
|
1492
|
-
* `executorAccount`" instead of presenting a
|
|
1493
|
-
* after the author has spent a nonce on it.
|
|
1488
|
+
* account and key go in the warrant's `executor` and `executor_key`, and
|
|
1489
|
+
* whether this node holds `CAN_AUTHOR_ON_BEHALF` on the owning group.
|
|
1490
|
+
* `canAuthorOnBehalf: false` comes back as an answer rather than an error, as
|
|
1491
|
+
* it is the default state of every context, so a caller can say "an admin of
|
|
1492
|
+
* `groupId` must grant it to `executorAccount`" instead of presenting a
|
|
1493
|
+
* warrant that will be refused after the author has spent a nonce on it.
|
|
1494
1494
|
*
|
|
1495
1495
|
* `404` means the context belongs to no group, or this node holds no account
|
|
1496
1496
|
* yet; either way it can be named as no warrant's executor.
|
|
@@ -7199,6 +7199,7 @@ async function signWarrant(input) {
|
|
|
7199
7199
|
const context = fromHex(input.context, "context", 32);
|
|
7200
7200
|
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
7201
7201
|
const executor = fromHex(input.executor, "executor", 32);
|
|
7202
|
+
const executorKey = fromHex(input.executorKey, "executorKey", 32);
|
|
7202
7203
|
const appVersion = fromHex(
|
|
7203
7204
|
input.appVersion ?? UNPINNED_APP,
|
|
7204
7205
|
"appVersion",
|
|
@@ -7217,6 +7218,7 @@ async function signWarrant(input) {
|
|
|
7217
7218
|
authorAccount,
|
|
7218
7219
|
publicKey,
|
|
7219
7220
|
executor,
|
|
7221
|
+
executorKey,
|
|
7220
7222
|
appVersion,
|
|
7221
7223
|
method,
|
|
7222
7224
|
commitment,
|
|
@@ -7234,6 +7236,7 @@ async function signWarrant(input) {
|
|
|
7234
7236
|
authorAccount,
|
|
7235
7237
|
publicKey,
|
|
7236
7238
|
executor,
|
|
7239
|
+
executorKey,
|
|
7237
7240
|
appVersion,
|
|
7238
7241
|
u32le(method.length),
|
|
7239
7242
|
method,
|
|
@@ -7280,6 +7283,7 @@ async function creationWarrantPreimage(p) {
|
|
|
7280
7283
|
p.authorAccount,
|
|
7281
7284
|
p.deviceKey,
|
|
7282
7285
|
p.executor,
|
|
7286
|
+
p.executorKey,
|
|
7283
7287
|
p.applicationId,
|
|
7284
7288
|
new Uint8Array([p.serviceName === null ? 0 : 1]),
|
|
7285
7289
|
p.serviceName ?? new Uint8Array(0),
|
|
@@ -7299,6 +7303,7 @@ async function signCreationWarrant(input) {
|
|
|
7299
7303
|
const seed = input.seed === void 0 ? crypto.getRandomValues(new Uint8Array(32)) : fromHex(input.seed, "seed", 32);
|
|
7300
7304
|
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
7301
7305
|
const executor = fromHex(input.executor, "executor", 32);
|
|
7306
|
+
const executorKey = fromHex(input.executorKey, "executorKey", 32);
|
|
7302
7307
|
const applicationId = fromHex(input.applicationId, "applicationId", 32);
|
|
7303
7308
|
const serviceName = label(input.serviceName, "serviceName");
|
|
7304
7309
|
const name = label(input.name, "name");
|
|
@@ -7313,6 +7318,7 @@ async function signCreationWarrant(input) {
|
|
|
7313
7318
|
authorAccount,
|
|
7314
7319
|
deviceKey,
|
|
7315
7320
|
executor,
|
|
7321
|
+
executorKey,
|
|
7316
7322
|
applicationId,
|
|
7317
7323
|
serviceName,
|
|
7318
7324
|
name,
|
|
@@ -7330,6 +7336,7 @@ async function signCreationWarrant(input) {
|
|
|
7330
7336
|
authorAccount,
|
|
7331
7337
|
deviceKey,
|
|
7332
7338
|
executor,
|
|
7339
|
+
executorKey,
|
|
7333
7340
|
applicationId,
|
|
7334
7341
|
borshOption(serviceName),
|
|
7335
7342
|
borshOption(name),
|
|
@@ -7389,6 +7396,7 @@ function parseCreationWarrant(warrant) {
|
|
|
7389
7396
|
authorAccount: hex(take(32, "authorAccount")),
|
|
7390
7397
|
deviceKey: hex(take(32, "deviceKey")),
|
|
7391
7398
|
executor: hex(take(32, "executor")),
|
|
7399
|
+
executorKey: hex(take(32, "executorKey")),
|
|
7392
7400
|
applicationId: hex(take(32, "applicationId")),
|
|
7393
7401
|
serviceName: option("serviceName"),
|
|
7394
7402
|
name: option("name"),
|
|
@@ -7435,6 +7443,7 @@ async function governanceWarrantPreimage(p) {
|
|
|
7435
7443
|
p.authorAccount,
|
|
7436
7444
|
p.deviceKey,
|
|
7437
7445
|
p.executor,
|
|
7446
|
+
p.executorKey,
|
|
7438
7447
|
p.opHash,
|
|
7439
7448
|
u64le(p.accountHeads.length),
|
|
7440
7449
|
...p.accountHeads,
|
|
@@ -7448,6 +7457,7 @@ async function signGovernanceWarrant(input) {
|
|
|
7448
7457
|
const scope = fromHex(input.scope, "scope", 32);
|
|
7449
7458
|
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
7450
7459
|
const executor = fromHex(input.executor, "executor", 32);
|
|
7460
|
+
const executorKey = fromHex(input.executorKey, "executorKey", 32);
|
|
7451
7461
|
const accountHeads = citedHeads(input.accountHeads, "accountHeads");
|
|
7452
7462
|
const governanceFloor = citedHeads(input.governanceFloor, "governanceFloor");
|
|
7453
7463
|
const kind = kindByte(input.op.kind);
|
|
@@ -7460,6 +7470,7 @@ async function signGovernanceWarrant(input) {
|
|
|
7460
7470
|
authorAccount,
|
|
7461
7471
|
deviceKey,
|
|
7462
7472
|
executor,
|
|
7473
|
+
executorKey,
|
|
7463
7474
|
opHash,
|
|
7464
7475
|
accountHeads,
|
|
7465
7476
|
governanceFloor,
|
|
@@ -7474,6 +7485,7 @@ async function signGovernanceWarrant(input) {
|
|
|
7474
7485
|
authorAccount,
|
|
7475
7486
|
deviceKey,
|
|
7476
7487
|
executor,
|
|
7488
|
+
executorKey,
|
|
7477
7489
|
opHash,
|
|
7478
7490
|
u32le(accountHeads.length),
|
|
7479
7491
|
...accountHeads,
|
|
@@ -7525,6 +7537,7 @@ function parseGovernanceWarrant(warrant) {
|
|
|
7525
7537
|
authorAccount: hex(take(32, "authorAccount")),
|
|
7526
7538
|
deviceKey: hex(take(32, "deviceKey")),
|
|
7527
7539
|
executor: hex(take(32, "executor")),
|
|
7540
|
+
executorKey: hex(take(32, "executorKey")),
|
|
7528
7541
|
opHash: hex(take(32, "opHash")),
|
|
7529
7542
|
accountHeads: heads("accountHeads"),
|
|
7530
7543
|
governanceFloor: heads("governanceFloor"),
|
|
@@ -7829,7 +7842,6 @@ var RelayClient = class {
|
|
|
7829
7842
|
constructor(config) {
|
|
7830
7843
|
this.config = config;
|
|
7831
7844
|
this.baseUrl = config.relayUrl.replace(/\/+$/, "");
|
|
7832
|
-
this.executorAccount = config.executorAccount;
|
|
7833
7845
|
const injected = config.fetch;
|
|
7834
7846
|
this.fetchImpl = injected ? (input, init) => injected(input, init) : (input, init) => globalThis.fetch(input, init);
|
|
7835
7847
|
this.timeoutMs = config.timeoutMs ?? 1e4;
|
|
@@ -7879,8 +7891,11 @@ var RelayClient = class {
|
|
|
7879
7891
|
* as diagnostics after a failure.
|
|
7880
7892
|
*/
|
|
7881
7893
|
async describe(contextId) {
|
|
7882
|
-
const body = await this.json(
|
|
7883
|
-
|
|
7894
|
+
const body = await this.json(
|
|
7895
|
+
"GET",
|
|
7896
|
+
`/admin-api/contexts/${encodeURIComponent(contextId)}/intents`
|
|
7897
|
+
);
|
|
7898
|
+
this.checkedExecutor(body.data);
|
|
7884
7899
|
return body.data;
|
|
7885
7900
|
}
|
|
7886
7901
|
/**
|
|
@@ -7891,14 +7906,15 @@ var RelayClient = class {
|
|
|
7891
7906
|
* apply. Nothing accumulates and nothing is reusable.
|
|
7892
7907
|
*/
|
|
7893
7908
|
async execute(contextId, method, argsJson = {}) {
|
|
7894
|
-
const executor = this.
|
|
7909
|
+
const executor = this.executor ?? this.checkedExecutor(await this.describe(contextId));
|
|
7895
7910
|
const signer = await this.authorSigner();
|
|
7896
7911
|
const nonce2 = await this.config.nonces.next();
|
|
7897
7912
|
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
7898
7913
|
const warrant = await signWarrant({
|
|
7899
7914
|
context: contextId,
|
|
7900
7915
|
authorAccount: this.config.authorAccount,
|
|
7901
|
-
executor,
|
|
7916
|
+
executor: executor.executorAccount,
|
|
7917
|
+
executorKey: executor.executorKey,
|
|
7902
7918
|
method,
|
|
7903
7919
|
argsJson,
|
|
7904
7920
|
nonce: nonce2,
|
|
@@ -7909,7 +7925,10 @@ var RelayClient = class {
|
|
|
7909
7925
|
"POST",
|
|
7910
7926
|
`/admin-api/contexts/${encodeURIComponent(contextId)}/intents`,
|
|
7911
7927
|
{ method, argsJson, warrant, authorProof: this.config.authorProof }
|
|
7912
|
-
)
|
|
7928
|
+
).catch((err) => {
|
|
7929
|
+
if (err instanceof IntentRefusedError) this.executor = void 0;
|
|
7930
|
+
throw err;
|
|
7931
|
+
});
|
|
7913
7932
|
return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
|
|
7914
7933
|
}
|
|
7915
7934
|
/**
|
|
@@ -7978,7 +7997,7 @@ var RelayClient = class {
|
|
|
7978
7997
|
403
|
|
7979
7998
|
);
|
|
7980
7999
|
}
|
|
7981
|
-
const executor = this.checkedExecutor(described
|
|
8000
|
+
const executor = this.checkedExecutor(described);
|
|
7982
8001
|
const initArgs = input.initArgs ?? {};
|
|
7983
8002
|
const signer = await this.authorSigner();
|
|
7984
8003
|
const nonce2 = await this.config.nonces.next();
|
|
@@ -7987,7 +8006,8 @@ var RelayClient = class {
|
|
|
7987
8006
|
group: input.groupId,
|
|
7988
8007
|
seed: input.seed,
|
|
7989
8008
|
authorAccount: this.config.authorAccount,
|
|
7990
|
-
executor,
|
|
8009
|
+
executor: executor.executorAccount,
|
|
8010
|
+
executorKey: executor.executorKey,
|
|
7991
8011
|
applicationId: input.applicationId,
|
|
7992
8012
|
serviceName: input.serviceName,
|
|
7993
8013
|
name: input.name,
|
|
@@ -8009,7 +8029,7 @@ var RelayClient = class {
|
|
|
8009
8029
|
}
|
|
8010
8030
|
/**
|
|
8011
8031
|
* Ask the relay whether it may publish governance ops for members of
|
|
8012
|
-
* `groupId`, and which account a warrant must name.
|
|
8032
|
+
* `groupId`, and which account and key a warrant must name.
|
|
8013
8033
|
*/
|
|
8014
8034
|
async describeGovernance(groupId) {
|
|
8015
8035
|
const body = await this.json(
|
|
@@ -8043,7 +8063,7 @@ var RelayClient = class {
|
|
|
8043
8063
|
403
|
|
8044
8064
|
);
|
|
8045
8065
|
}
|
|
8046
|
-
const executor = this.checkedExecutor(described
|
|
8066
|
+
const executor = this.checkedExecutor(described);
|
|
8047
8067
|
const signer = await this.authorSigner();
|
|
8048
8068
|
const nonce2 = await this.config.nonces.next();
|
|
8049
8069
|
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
@@ -8051,7 +8071,8 @@ var RelayClient = class {
|
|
|
8051
8071
|
scope: input.groupId,
|
|
8052
8072
|
op: input.op,
|
|
8053
8073
|
authorAccount: this.config.authorAccount,
|
|
8054
|
-
executor,
|
|
8074
|
+
executor: executor.executorAccount,
|
|
8075
|
+
executorKey: executor.executorKey,
|
|
8055
8076
|
nonce: nonce2,
|
|
8056
8077
|
notAfter: BigInt(Math.floor(Date.now() / 1e3)) + BigInt(ttl),
|
|
8057
8078
|
signer
|
|
@@ -8077,9 +8098,7 @@ var RelayClient = class {
|
|
|
8077
8098
|
*
|
|
8078
8099
|
* The executor cannot be learned from the relay first: the namespace does not
|
|
8079
8100
|
* exist, so `describeGovernance` has nothing to answer about. It comes from
|
|
8080
|
-
* `input.
|
|
8081
|
-
* (`describe`, `createContext`, `govern`), and without any of them this
|
|
8082
|
-
* throws before taking a nonce.
|
|
8101
|
+
* `input.executor` only, and without it this throws before taking a nonce.
|
|
8083
8102
|
* The nonce is spent in the new namespace's ledger.
|
|
8084
8103
|
*
|
|
8085
8104
|
* With `defaultCapabilities`, the founder then sets the namespace's default
|
|
@@ -8090,13 +8109,13 @@ var RelayClient = class {
|
|
|
8090
8109
|
* Refusals (`400`/`403`) come back as {@link IntentRefusedError}; a salt
|
|
8091
8110
|
* that names an existing namespace is a `409`, an `HTTPError`.
|
|
8092
8111
|
*/
|
|
8093
|
-
async foundNamespace(input
|
|
8094
|
-
|
|
8095
|
-
if (!executor) {
|
|
8112
|
+
async foundNamespace(input) {
|
|
8113
|
+
if (!input?.executor) {
|
|
8096
8114
|
throw new Error(
|
|
8097
|
-
"foundNamespace needs the relay's account
|
|
8115
|
+
"foundNamespace needs the relay's account and signing key: pass executor (checked before signing, no nonce was spent)"
|
|
8098
8116
|
);
|
|
8099
8117
|
}
|
|
8118
|
+
const executor = this.checkedExecutor(input.executor);
|
|
8100
8119
|
const salt = input.salt ? hex(fromHex(input.salt, "salt", 32)) : hex(crypto.getRandomValues(new Uint8Array(32)));
|
|
8101
8120
|
const namespaceId = await foundedNamespaceId(this.config.authorAccount, salt);
|
|
8102
8121
|
const op = namespaceCreatedOp({
|
|
@@ -8113,7 +8132,8 @@ var RelayClient = class {
|
|
|
8113
8132
|
scope: namespaceId,
|
|
8114
8133
|
op,
|
|
8115
8134
|
authorAccount: this.config.authorAccount,
|
|
8116
|
-
executor,
|
|
8135
|
+
executor: executor.executorAccount,
|
|
8136
|
+
executorKey: executor.executorKey,
|
|
8117
8137
|
nonce: nonce2,
|
|
8118
8138
|
notAfter: BigInt(Math.floor(Date.now() / 1e3)) + BigInt(ttl),
|
|
8119
8139
|
signer
|
|
@@ -8154,18 +8174,22 @@ var RelayClient = class {
|
|
|
8154
8174
|
return body.data;
|
|
8155
8175
|
}
|
|
8156
8176
|
/**
|
|
8157
|
-
* The
|
|
8158
|
-
*
|
|
8177
|
+
* The relay's answer, checked against a configured account and remembered.
|
|
8178
|
+
* Decoded here so a relay naming no key is refused before a nonce is taken.
|
|
8159
8179
|
*/
|
|
8160
8180
|
checkedExecutor(answered) {
|
|
8181
|
+
const executor = {
|
|
8182
|
+
executorAccount: hex(fromHex(answered.executorAccount ?? "", "the relay's executorAccount", 32)),
|
|
8183
|
+
executorKey: hex(fromHex(answered.executorKey ?? "", "the relay's executorKey", 32))
|
|
8184
|
+
};
|
|
8161
8185
|
const configured = this.config.executorAccount;
|
|
8162
|
-
if (configured && configured.toLowerCase() !==
|
|
8186
|
+
if (configured && configured.toLowerCase() !== executor.executorAccount) {
|
|
8163
8187
|
throw new Error(
|
|
8164
|
-
`configured executorAccount ${configured} is not the relay's account ${
|
|
8188
|
+
`configured executorAccount ${configured} is not the relay's account ${executor.executorAccount}; a warrant naming it would be unspendable`
|
|
8165
8189
|
);
|
|
8166
8190
|
}
|
|
8167
|
-
this.
|
|
8168
|
-
return
|
|
8191
|
+
this.executor = executor;
|
|
8192
|
+
return executor;
|
|
8169
8193
|
}
|
|
8170
8194
|
/**
|
|
8171
8195
|
* One request, waiting out a rate limit rather than failing the caller.
|
|
@@ -10507,19 +10531,10 @@ async function foundDelegatedNamespace(s, req = {}, deps = {}) {
|
|
|
10507
10531
|
const relays = knownRelays(s).map((u) => u.replace(/\/+$/, ""));
|
|
10508
10532
|
const relay = relays[0];
|
|
10509
10533
|
if (!relay) throw new Error("no relay is known for this account, so there is nowhere to found a namespace");
|
|
10510
|
-
const
|
|
10511
|
-
([, url]) => url.replace(/\/+$/, "") === relay
|
|
10512
|
-
)?.[0];
|
|
10513
|
-
const named = s.executorAccount && s.relayUrl && s.relayUrl.replace(/\/+$/, "") === relay ? s.executorAccount : null;
|
|
10514
|
-
if (!named && !known) {
|
|
10515
|
-
throw new Error(
|
|
10516
|
-
"the executor account of this relay is not known: join a namespace on it first, or connect with the relay's executor account (the cloud shows it beside the relay)"
|
|
10517
|
-
);
|
|
10518
|
-
}
|
|
10519
|
-
const executorAccount = named ?? (await client(s, relay, governanceNonce(relay, known), deps.fetch).describeGovernance(known)).executorAccount;
|
|
10534
|
+
const executor = await foundingExecutor(s, relay, deps.fetch);
|
|
10520
10535
|
let next = BigInt(Date.now());
|
|
10521
10536
|
const founded = await client(s, relay, { next: async () => next++ }, deps.fetch).foundNamespace({
|
|
10522
|
-
|
|
10537
|
+
executor,
|
|
10523
10538
|
...req.defaultCapabilities !== void 0 ? { defaultCapabilities: req.defaultCapabilities } : {},
|
|
10524
10539
|
...req.application ? { application: req.application } : {}
|
|
10525
10540
|
});
|
|
@@ -10539,6 +10554,33 @@ async function foundDelegatedNamespace(s, req = {}, deps = {}) {
|
|
|
10539
10554
|
};
|
|
10540
10555
|
return { namespaceId: founded.namespaceId, teeEnabled: founded.teeEnabled, ...ha };
|
|
10541
10556
|
}
|
|
10557
|
+
async function foundingExecutor(s, relay, fetch2) {
|
|
10558
|
+
const named = s.executorAccount && s.relayUrl?.replace(/\/+$/, "") === relay ? s.executorAccount : null;
|
|
10559
|
+
if (named) return { executorAccount: named, executorKey: await attestedNodeKey(relay) };
|
|
10560
|
+
const known = Object.entries(readRelayMap(s.account).namespaces).find(
|
|
10561
|
+
([, url]) => url.replace(/\/+$/, "") === relay
|
|
10562
|
+
)?.[0];
|
|
10563
|
+
if (!known) {
|
|
10564
|
+
throw new Error(
|
|
10565
|
+
"the executor account of this relay is not known: join a namespace on it first, or connect with the relay's executor account (the cloud shows it beside the relay)"
|
|
10566
|
+
);
|
|
10567
|
+
}
|
|
10568
|
+
const executorKey = await attestedNodeKey(relay);
|
|
10569
|
+
const described = await client(s, relay, governanceNonce(relay, known), fetch2).describeGovernance(known);
|
|
10570
|
+
if (described.executorKey?.toLowerCase() !== executorKey) {
|
|
10571
|
+
throw new Error(
|
|
10572
|
+
`the relay's discovery names signing key ${described.executorKey}, not the relay's node key ${executorKey}: refusing to found through it`
|
|
10573
|
+
);
|
|
10574
|
+
}
|
|
10575
|
+
return { executorAccount: described.executorAccount, executorKey };
|
|
10576
|
+
}
|
|
10577
|
+
async function attestedNodeKey(relay) {
|
|
10578
|
+
const key = await attemptRelayNodeKey(relay);
|
|
10579
|
+
if (key.kind === "learned") return key.nodeKey;
|
|
10580
|
+
throw new Error(
|
|
10581
|
+
key.kind === "unavailable" ? "the relay's signing key could not be learned: its attestation did not answer, try again" : "the relay's attestation was refused, so founding through it is not possible (only a key from its operator, pinned with pinRelayNodeKey, can stand in)"
|
|
10582
|
+
);
|
|
10583
|
+
}
|
|
10542
10584
|
var HA_ACCOUNT_NOT_LINKED_MESSAGE = "link this account to your cloud user in the wallet so invitees can find this namespace";
|
|
10543
10585
|
var HA_REFUSAL_MESSAGES = {
|
|
10544
10586
|
account_not_linked: HA_ACCOUNT_NOT_LINKED_MESSAGE,
|