@calimero-network/mero-js 26.10.0 → 27.0.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/README.md +73 -288
- package/dist/cloud-v2/attestation.d.ts +91 -0
- package/dist/cloud-v2/attestation.js +135 -0
- package/dist/cloud-v2/capabilities.d.ts +30 -0
- package/dist/cloud-v2/capabilities.js +31 -0
- package/dist/cloud-v2/client.d.ts +426 -0
- package/dist/cloud-v2/client.js +646 -0
- package/dist/cloud-v2/errors.d.ts +98 -0
- package/dist/cloud-v2/errors.js +165 -0
- package/dist/cloud-v2/index.d.ts +10 -0
- package/dist/cloud-v2/index.js +5 -0
- package/dist/cloud-v2/passkey.d.ts +27 -0
- package/dist/cloud-v2/passkey.js +73 -0
- package/dist/crypto/internal.d.ts +3 -37
- package/dist/crypto/internal.js +3 -72
- package/dist/index.browser.mjs +4 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +1750 -12767
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +3 -56
- package/dist/index.js +14 -75
- package/dist/index.mjs +1750 -12767
- package/dist/index.mjs.map +4 -4
- package/dist/sealed/index.d.ts +4 -4
- package/dist/sealed/index.js +2 -2
- package/dist/sealed/release.d.ts +21 -76
- package/dist/sealed/release.js +24 -108
- package/dist/sealed/sealed.d.ts +8 -56
- package/dist/sealed/sealed.js +11 -89
- package/dist/sealed/verify.d.ts +7 -13
- package/dist/sealed/verify.js +3 -7
- package/package.json +8 -13
- package/dist/account/account-admin.d.ts +0 -80
- package/dist/account/account-admin.js +0 -346
- package/dist/account/account.d.ts +0 -196
- package/dist/account/account.js +0 -269
- package/dist/account/application-id.d.ts +0 -50
- package/dist/account/application-id.js +0 -83
- package/dist/account/bootstrap-from-invitation.d.ts +0 -110
- package/dist/account/bootstrap-from-invitation.js +0 -80
- package/dist/account/create-context.d.ts +0 -103
- package/dist/account/create-context.js +0 -267
- package/dist/account/govern.d.ts +0 -24
- package/dist/account/govern.js +0 -50
- package/dist/account/index.d.ts +0 -26
- package/dist/account/index.js +0 -15
- package/dist/account/join-as-account.d.ts +0 -23
- package/dist/account/join-as-account.js +0 -34
- package/dist/account/join-with-node.d.ts +0 -115
- package/dist/account/join-with-node.js +0 -161
- package/dist/account/node-admin.d.ts +0 -20
- package/dist/account/node-admin.js +0 -33
- package/dist/account/relay-from-invitation.d.ts +0 -137
- package/dist/account/relay-from-invitation.js +0 -180
- package/dist/account/relay-login-error.d.ts +0 -32
- package/dist/account/relay-login-error.js +0 -34
- package/dist/account/session.d.ts +0 -266
- package/dist/account/session.js +0 -915
- package/dist/account/wordlist.d.ts +0 -16
- package/dist/account/wordlist.js +0 -273
- package/dist/admin-api/admin-client.d.ts +0 -686
- package/dist/admin-api/admin-client.js +0 -1225
- package/dist/admin-api/admin-factory.d.ts +0 -14
- package/dist/admin-api/admin-factory.js +0 -22
- package/dist/admin-api/admin-types.d.ts +0 -2041
- package/dist/admin-api/admin-types.js +0 -12
- package/dist/admin-api/index.d.ts +0 -4
- package/dist/admin-api/index.js +0 -5
- package/dist/admin-api/redeem-invitation.d.ts +0 -101
- package/dist/admin-api/redeem-invitation.js +0 -200
- package/dist/auth/index.d.ts +0 -34
- package/dist/auth/index.js +0 -67
- package/dist/auth-api/auth-client.d.ts +0 -31
- package/dist/auth-api/auth-client.js +0 -117
- package/dist/auth-api/auth-factory.d.ts +0 -7
- package/dist/auth-api/auth-factory.js +0 -41
- package/dist/auth-api/auth-types.d.ts +0 -130
- package/dist/auth-api/auth-types.js +0 -2
- package/dist/auth-api/index.d.ts +0 -3
- package/dist/auth-api/index.js +0 -4
- package/dist/capabilities.d.ts +0 -84
- package/dist/capabilities.js +0 -117
- package/dist/cloud/account-ownership.d.ts +0 -63
- package/dist/cloud/account-ownership.js +0 -87
- package/dist/cloud/cloud-client.d.ts +0 -949
- package/dist/cloud/cloud-client.js +0 -1068
- package/dist/cloud/connect.d.ts +0 -213
- package/dist/cloud/connect.js +0 -260
- package/dist/cloud/enrol-redirect.d.ts +0 -181
- package/dist/cloud/enrol-redirect.js +0 -244
- package/dist/cloud/index.d.ts +0 -12
- package/dist/cloud/index.js +0 -10
- package/dist/cloud/link-redirect.d.ts +0 -95
- package/dist/cloud/link-redirect.js +0 -121
- package/dist/cloud/link-state.d.ts +0 -36
- package/dist/cloud/link-state.js +0 -104
- package/dist/cloud/routing-proof.d.ts +0 -113
- package/dist/cloud/routing-proof.js +0 -96
- package/dist/device-cert/device-cert.d.ts +0 -189
- package/dist/device-cert/device-cert.js +0 -239
- package/dist/device-cert/device-scope.d.ts +0 -58
- package/dist/device-cert/device-scope.js +0 -76
- package/dist/device-cert/index.d.ts +0 -4
- package/dist/device-cert/index.js +0 -3
- package/dist/ephemeral/codec.d.ts +0 -4
- package/dist/ephemeral/codec.js +0 -12
- package/dist/ephemeral/index.d.ts +0 -57
- package/dist/ephemeral/index.js +0 -101
- package/dist/ephemeral/types.d.ts +0 -27
- package/dist/ephemeral/types.js +0 -1
- package/dist/errors/classify.d.ts +0 -65
- package/dist/errors/classify.js +0 -117
- package/dist/errors/index.d.ts +0 -2
- package/dist/errors/index.js +0 -1
- package/dist/events/group.d.ts +0 -95
- package/dist/events/group.js +0 -10
- package/dist/events/index.d.ts +0 -5
- package/dist/events/index.js +0 -2
- package/dist/events/sse.d.ts +0 -127
- package/dist/events/sse.js +0 -469
- package/dist/events/ws.d.ts +0 -57
- package/dist/events/ws.js +0 -212
- package/dist/http-client/api-response.d.ts +0 -15
- package/dist/http-client/api-response.js +0 -1
- package/dist/http-client/http-factory.d.ts +0 -71
- package/dist/http-client/http-factory.js +0 -68
- package/dist/http-client/http-types.d.ts +0 -87
- package/dist/http-client/http-types.js +0 -1
- package/dist/http-client/index.d.ts +0 -7
- package/dist/http-client/index.js +0 -11
- package/dist/http-client/path-segment.d.ts +0 -1
- package/dist/http-client/path-segment.js +0 -8
- package/dist/http-client/retry.d.ts +0 -5
- package/dist/http-client/retry.js +0 -82
- package/dist/http-client/signal-utils.d.ts +0 -2
- package/dist/http-client/signal-utils.js +0 -41
- package/dist/http-client/web-client.d.ts +0 -80
- package/dist/http-client/web-client.js +0 -557
- package/dist/invitation/index.d.ts +0 -2
- package/dist/invitation/index.js +0 -2
- package/dist/invitation/invitation.d.ts +0 -106
- package/dist/invitation/invitation.js +0 -104
- package/dist/login/index.d.ts +0 -4
- package/dist/login/index.js +0 -3
- package/dist/login/login.d.ts +0 -111
- package/dist/login/login.js +0 -110
- package/dist/login/session.d.ts +0 -124
- package/dist/login/session.js +0 -141
- package/dist/mero-js.d.ts +0 -231
- package/dist/mero-js.js +0 -469
- package/dist/namespace-op/index.d.ts +0 -2
- package/dist/namespace-op/index.js +0 -3
- package/dist/namespace-op/namespace-op.d.ts +0 -150
- package/dist/namespace-op/namespace-op.js +0 -191
- package/dist/nodeDiscovery.d.ts +0 -47
- package/dist/nodeDiscovery.js +0 -101
- package/dist/owner-op/index.d.ts +0 -2
- package/dist/owner-op/index.js +0 -3
- package/dist/owner-op/owner-op.d.ts +0 -119
- package/dist/owner-op/owner-op.js +0 -214
- package/dist/presence/relay-presence.d.ts +0 -56
- package/dist/presence/relay-presence.js +0 -107
- package/dist/presence/statement.d.ts +0 -12
- package/dist/presence/statement.js +0 -17
- package/dist/relay/index.d.ts +0 -4
- package/dist/relay/index.js +0 -2
- package/dist/relay/nonce-source.d.ts +0 -72
- package/dist/relay/nonce-source.js +0 -111
- package/dist/relay/relay-client.d.ts +0 -472
- package/dist/relay/relay-client.js +0 -518
- package/dist/relay-attestation/attest-node-key.d.ts +0 -66
- package/dist/relay-attestation/attest-node-key.js +0 -110
- package/dist/relay-attestation/index.d.ts +0 -1
- package/dist/relay-attestation/index.js +0 -1
- package/dist/request/caller-proof.d.ts +0 -43
- package/dist/request/caller-proof.js +0 -36
- package/dist/request/index.d.ts +0 -3
- package/dist/request/index.js +0 -3
- package/dist/request/proof-signer.d.ts +0 -49
- package/dist/request/proof-signer.js +0 -59
- package/dist/request/request-sig.d.ts +0 -99
- package/dist/request/request-sig.js +0 -95
- package/dist/request-proof/authorizer.d.ts +0 -41
- package/dist/request-proof/authorizer.js +0 -60
- package/dist/request-proof/index.d.ts +0 -4
- package/dist/request-proof/index.js +0 -2
- package/dist/request-proof/request-proof.d.ts +0 -53
- package/dist/request-proof/request-proof.js +0 -95
- package/dist/rpc/index.d.ts +0 -64
- package/dist/rpc/index.js +0 -78
- package/dist/signer/index.d.ts +0 -2
- package/dist/signer/index.js +0 -3
- package/dist/signer/signer.d.ts +0 -92
- package/dist/signer/signer.js +0 -147
- package/dist/token-store/index.d.ts +0 -27
- package/dist/token-store/index.js +0 -62
- package/dist/transport/index.d.ts +0 -6
- package/dist/transport/index.js +0 -3
- package/dist/transport/mero-client.d.ts +0 -294
- package/dist/transport/mero-client.js +0 -386
- package/dist/transport/relay-observer.d.ts +0 -152
- package/dist/transport/relay-observer.js +0 -173
- package/dist/transport/relay-transport.d.ts +0 -73
- package/dist/transport/relay-transport.js +0 -94
- package/dist/transport/types.d.ts +0 -100
- package/dist/transport/types.js +0 -32
- package/dist/types/api-response.d.ts +0 -15
- package/dist/types/api-response.js +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/warrant/creation-warrant.d.ts +0 -163
- package/dist/warrant/creation-warrant.js +0 -194
- package/dist/warrant/governance-op.d.ts +0 -202
- package/dist/warrant/governance-op.js +0 -355
- package/dist/warrant/governance-warrant.d.ts +0 -124
- package/dist/warrant/governance-warrant.js +0 -164
- package/dist/warrant/index.d.ts +0 -8
- package/dist/warrant/index.js +0 -5
- package/dist/warrant/warrant.d.ts +0 -188
- package/dist/warrant/warrant.js +0 -202
|
@@ -1,472 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Write to a context through a relay, holding nothing but a signing key.
|
|
3
|
-
*
|
|
4
|
-
* # What this replaces
|
|
5
|
-
*
|
|
6
|
-
* `sdk.rpc.execute` asks a node to run a method *as itself*: it needs a node,
|
|
7
|
-
* that node needs to be a member, and the caller needs a credential on it. For
|
|
8
|
-
* a browser tab, a phone, or an agent, none of those three is available — the
|
|
9
|
-
* runtime cannot compile WASM against materialized state, never received the
|
|
10
|
-
* scope key that seals the deltas, and has no account on anybody's node.
|
|
11
|
-
*
|
|
12
|
-
* This client is the other path. The caller signs a warrant locally, the relay
|
|
13
|
-
* runs the method as the *author's* principal, and the resulting delta is
|
|
14
|
-
* attributed to the author's account and device — their replica slot, their
|
|
15
|
-
* membership, their name in the app. The relay's key signs the envelope and
|
|
16
|
-
* nothing else.
|
|
17
|
-
*
|
|
18
|
-
* # The three preconditions, and why they are checked in this order
|
|
19
|
-
*
|
|
20
|
-
* `describe()` answers the first two in one call, before anything is signed:
|
|
21
|
-
* the relay's executor account and signing key and the release the context's
|
|
22
|
-
* group names (which the warrant must name), and whether it holds
|
|
23
|
-
* `CAN_AUTHOR_ON_BEHALF` on the owning group. The third,
|
|
24
|
-
* that the author's account is a member, only the group knows, and it surfaces
|
|
25
|
-
* as a refusal.
|
|
26
|
-
*
|
|
27
|
-
* Checking before signing is not politeness. A warrant consumes a nonce from a
|
|
28
|
-
* monotonic per-device sequence, and one minted against the wrong executor is
|
|
29
|
-
* unspendable: the number is gone and the write never happened.
|
|
30
|
-
*/
|
|
31
|
-
import { type Signer } from '../signer/signer.js';
|
|
32
|
-
import { type GovernanceOp } from '../warrant/governance-op.js';
|
|
33
|
-
import type { NonceSource } from './nonce-source.js';
|
|
34
|
-
/** Where and as whom to write, plus the key that consents. */
|
|
35
|
-
export interface RelayClientConfig {
|
|
36
|
-
/**
|
|
37
|
-
* The relay's base URL — the node's origin, not a path.
|
|
38
|
-
*
|
|
39
|
-
* Discover it from {@link CloudClient.getNamespaceRelays} for a hosted
|
|
40
|
-
* namespace, or take it from the operator for a self-hosted one.
|
|
41
|
-
*/
|
|
42
|
-
relayUrl: string;
|
|
43
|
-
/**
|
|
44
|
-
* The account the relay writes as, hex — a warrant's `executor`.
|
|
45
|
-
*
|
|
46
|
-
* Only checked against what the relay answers: a warrant also names the
|
|
47
|
-
* relay's signing key and the release, which only discovery reports, so every write asks.
|
|
48
|
-
*/
|
|
49
|
-
executorAccount?: string;
|
|
50
|
-
/** The author's account, hex — whose consent the warrant carries. */
|
|
51
|
-
authorAccount: string;
|
|
52
|
-
/**
|
|
53
|
-
* The author's `AccountProof<DeviceCert>`, hex-encoded borsh.
|
|
54
|
-
*
|
|
55
|
-
* Proves the key that signed the warrant is a device of the account it names.
|
|
56
|
-
* The author sends only its own half; the relay attaches its own.
|
|
57
|
-
*/
|
|
58
|
-
authorProof: string;
|
|
59
|
-
/**
|
|
60
|
-
* The author device's ed25519 signing secret, hex (32 bytes).
|
|
61
|
-
*
|
|
62
|
-
* Never transmitted. It signs in this process and only the signature leaves,
|
|
63
|
-
* which is the whole reason a keyholder can author without a node.
|
|
64
|
-
*
|
|
65
|
-
* Mutually exclusive with {@link RelayClientConfig.signer}: exactly one is
|
|
66
|
-
* required. A browser should prefer the signer: a secret held as a string is
|
|
67
|
-
* readable by anything on the origin, and a non-extractable key is not.
|
|
68
|
-
*/
|
|
69
|
-
deviceSecret?: string;
|
|
70
|
-
/**
|
|
71
|
-
* The author device's signer: use instead of
|
|
72
|
-
* {@link RelayClientConfig.deviceSecret} when the key cannot be exported
|
|
73
|
-
* (a non-extractable WebCrypto key, a passkey, a hardware or remote signer).
|
|
74
|
-
*/
|
|
75
|
-
signer?: Signer;
|
|
76
|
-
/**
|
|
77
|
-
* Where nonces come from. See {@link NonceSource} — a reset replays.
|
|
78
|
-
*
|
|
79
|
-
* Persist it (`createLocalStorageNonceSource` in a browser): the node keeps
|
|
80
|
-
* the spent ledger but serves no lookup of it, so the client's own counter is
|
|
81
|
-
* the only record of where the sequence stands.
|
|
82
|
-
*/
|
|
83
|
-
nonces: NonceSource;
|
|
84
|
-
/**
|
|
85
|
-
* Seconds a minted warrant stays valid. Defaults to 300.
|
|
86
|
-
*
|
|
87
|
-
* Checked by the relay against its own clock, and by peers against the
|
|
88
|
-
* delta's own signed stamp, never their clocks: this bounds how long *this*
|
|
89
|
-
* request may sit in flight before the relay runs it.
|
|
90
|
-
*/
|
|
91
|
-
ttlSeconds?: number;
|
|
92
|
-
/** Injected for tests and non-browser runtimes. Defaults to global `fetch`. */
|
|
93
|
-
fetch?: typeof fetch;
|
|
94
|
-
timeoutMs?: number;
|
|
95
|
-
/**
|
|
96
|
-
* How many times a `429` is waited out before it reaches the caller.
|
|
97
|
-
* Defaults to 3; `0` surfaces rate limits immediately.
|
|
98
|
-
*
|
|
99
|
-
* Safe to retry because the relay's ingress limiter runs before the node sees
|
|
100
|
-
* the request, so a throttled warrant's nonce is not spent.
|
|
101
|
-
*/
|
|
102
|
-
rateLimitRetries?: number;
|
|
103
|
-
}
|
|
104
|
-
/** The relay a warrant names: its account, and the one key of it that may spend the warrant. */
|
|
105
|
-
export interface RelayExecutor {
|
|
106
|
-
/** The account a warrant must name as `executor`, hex. */
|
|
107
|
-
executorAccount: string;
|
|
108
|
-
/** The signing key a warrant must name as `executor_key`, hex. */
|
|
109
|
-
executorKey: string;
|
|
110
|
-
}
|
|
111
|
-
/** What a relay says about its ability to run intents in one context. */
|
|
112
|
-
export interface RelayDescription extends RelayExecutor {
|
|
113
|
-
/** Whether the relay holds `CAN_AUTHOR_ON_BEHALF` on the owning group. */
|
|
114
|
-
canAuthorOnBehalf: boolean;
|
|
115
|
-
/** The group whose admin grants that capability, hex. */
|
|
116
|
-
groupId: string;
|
|
117
|
-
/**
|
|
118
|
-
* The blob id of the release the group names, hex: what a warrant must pin
|
|
119
|
-
* as `release_bytecode_id`. Discovery answers 404 while the group names none.
|
|
120
|
-
*/
|
|
121
|
-
releaseBytecodeId: string;
|
|
122
|
-
/** That release's semver, signed as the warrant's `release_version`. */
|
|
123
|
-
releaseVersion: string;
|
|
124
|
-
}
|
|
125
|
-
/** What a relay says about its ability to create contexts in one group. */
|
|
126
|
-
export interface CreationDescription extends RelayExecutor {
|
|
127
|
-
/** The group, hex. */
|
|
128
|
-
groupId: string;
|
|
129
|
-
/**
|
|
130
|
-
* Whether the relay has standing to act for members of this group (a
|
|
131
|
-
* `RelayTee` role or `CAN_AUTHOR_ON_BEHALF`). It needs no create rights of
|
|
132
|
-
* its own — those are checked on the author.
|
|
133
|
-
*/
|
|
134
|
-
canCreateOnBehalf: boolean;
|
|
135
|
-
/**
|
|
136
|
-
* Whether the author holds `CAN_CREATE_CONTEXT` (or admin) here. Present only
|
|
137
|
-
* when `describeCreation` was given an `author`.
|
|
138
|
-
*/
|
|
139
|
-
authorMayCreate?: boolean;
|
|
140
|
-
}
|
|
141
|
-
/** What {@link RelayClient.createContext} creates. */
|
|
142
|
-
export interface CreateContextInput {
|
|
143
|
-
/** The group to create the context in, hex. */
|
|
144
|
-
groupId: string;
|
|
145
|
-
/** The application to create it with, hex (32 bytes). */
|
|
146
|
-
applicationId: string;
|
|
147
|
-
/** The JSON the app's `init()` receives — run as the author's account. */
|
|
148
|
-
initArgs?: unknown;
|
|
149
|
-
/** Which service of a multi-service bundle; absent for the default. */
|
|
150
|
-
serviceName?: string;
|
|
151
|
-
/** A display name for the context. */
|
|
152
|
-
name?: string;
|
|
153
|
-
/**
|
|
154
|
-
* The seed the context id is derived from, hex (32 bytes). Random when
|
|
155
|
-
* absent, which is what almost every caller wants.
|
|
156
|
-
*/
|
|
157
|
-
seed?: string;
|
|
158
|
-
}
|
|
159
|
-
/** Where a delegated creation landed. */
|
|
160
|
-
export interface CreatedContext {
|
|
161
|
-
/** The new context's id, hex. */
|
|
162
|
-
contextId: string;
|
|
163
|
-
/** The group it was created in, hex. */
|
|
164
|
-
groupId: string;
|
|
165
|
-
/** The relay's identity in the new context, hex. */
|
|
166
|
-
memberPublicKey: string;
|
|
167
|
-
}
|
|
168
|
-
/** What a relay says about publishing governance ops for members of one group. */
|
|
169
|
-
export interface GovernanceDescription extends RelayExecutor {
|
|
170
|
-
/** The group asked about, hex. */
|
|
171
|
-
groupId: string;
|
|
172
|
-
/**
|
|
173
|
-
* Whether the relay may act for members here (a `RelayTee` role or
|
|
174
|
-
* `CAN_AUTHOR_ON_BEHALF`). It needs no right to the op itself: that is
|
|
175
|
-
* checked on the author, as the op is applied as the author.
|
|
176
|
-
*/
|
|
177
|
-
canActOnBehalf: boolean;
|
|
178
|
-
}
|
|
179
|
-
/** What {@link RelayClient.govern} publishes. */
|
|
180
|
-
export interface GovernInput {
|
|
181
|
-
/**
|
|
182
|
-
* Where the op is published, hex: the group itself for a group op, the
|
|
183
|
-
* **namespace** for a root op (creating, moving or deleting a subgroup).
|
|
184
|
-
*/
|
|
185
|
-
groupId: string;
|
|
186
|
-
/** The op, from one of the encoders (`memberAddedOp`, `groupCreatedOp`, ...). */
|
|
187
|
-
op: GovernanceOp;
|
|
188
|
-
}
|
|
189
|
-
/** Where a delegated governance op landed. */
|
|
190
|
-
export interface GovernResult {
|
|
191
|
-
/** The group the op acted on, hex: the new subgroup, for a creation. */
|
|
192
|
-
groupId: string;
|
|
193
|
-
}
|
|
194
|
-
/** What {@link RelayClient.foundNamespace} founds with. */
|
|
195
|
-
export interface FoundNamespaceInput {
|
|
196
|
-
/**
|
|
197
|
-
* The salt the namespace id is derived from, hex (32 bytes). Random when
|
|
198
|
-
* absent, which is what almost every caller wants: one account founds many
|
|
199
|
-
* namespaces by varying it.
|
|
200
|
-
*/
|
|
201
|
-
salt?: string;
|
|
202
|
-
/**
|
|
203
|
-
* The relay's account and node key (pinned, or from `resolveRelayNodeKey`). Never
|
|
204
|
-
* a discovery answer: that key is unauthenticated, and no namespace exists yet.
|
|
205
|
-
*/
|
|
206
|
-
executor: RelayExecutor;
|
|
207
|
-
/**
|
|
208
|
-
* The namespace root's default capability mask (`MemberCapabilities` bits),
|
|
209
|
-
* set right after founding. A namespace is founded with core's minimal
|
|
210
|
-
* default (`CAN_JOIN_OPEN_SUBGROUPS` only), so an app that wants members to
|
|
211
|
-
* create contexts or invite, for example, names its own mask here.
|
|
212
|
-
*
|
|
213
|
-
* Set through the relay with a delegated `DefaultCapabilitiesSet`, applied as
|
|
214
|
-
* the founder, who is the namespace's admin. It cannot include
|
|
215
|
-
* `CAN_AUTHOR_ON_BEHALF` (bit 9): which relays may write for members is never
|
|
216
|
-
* decided through a relay, and such a mask is refused before anything is
|
|
217
|
-
* signed.
|
|
218
|
-
*/
|
|
219
|
-
defaultCapabilities?: number;
|
|
220
|
-
/**
|
|
221
|
-
* The application the namespace runs, set right after founding. Without one
|
|
222
|
-
* a founded namespace targets no application, and no context can be created
|
|
223
|
-
* in it. Set through the relay with a delegated `TargetApplicationSet`, which
|
|
224
|
-
* core accepts only as a group's first application.
|
|
225
|
-
*/
|
|
226
|
-
application?: {
|
|
227
|
-
applicationId: string;
|
|
228
|
-
package: string;
|
|
229
|
-
version: string;
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
/** A namespace founded through a relay. */
|
|
233
|
-
export interface FoundedNamespace {
|
|
234
|
-
/** The new namespace's id, hex: `foundedNamespaceId(author, salt)`. */
|
|
235
|
-
namespaceId: string;
|
|
236
|
-
/**
|
|
237
|
-
* The salt it was derived with, hex. Keep it if anyone will need to be shown
|
|
238
|
-
* who founded the namespace: `(founder, salt)` reproduces the id.
|
|
239
|
-
*/
|
|
240
|
-
salt: string;
|
|
241
|
-
/**
|
|
242
|
-
* Whether the relay admitted itself as the namespace's first TEE, which also
|
|
243
|
-
* sets its default relay-mode admission policy. `false` from a relay that is
|
|
244
|
-
* not a TEE, or whose attestation failed (see `teeError`). The namespace is
|
|
245
|
-
* founded either way.
|
|
246
|
-
*/
|
|
247
|
-
teeEnabled: boolean;
|
|
248
|
-
/** Why `teeEnabled` is `false`, when the relay tried and failed. */
|
|
249
|
-
teeError?: string;
|
|
250
|
-
/**
|
|
251
|
-
* Present only when `defaultCapabilities` was asked for: whether the mask was
|
|
252
|
-
* set. `false` leaves the namespace founded with core's default; retry with
|
|
253
|
-
* `govern({ groupId: namespaceId, op: defaultCapabilitiesSetOp(mask) })`.
|
|
254
|
-
*/
|
|
255
|
-
defaultCapabilitiesSet?: boolean;
|
|
256
|
-
/** Why `defaultCapabilitiesSet` is `false`. */
|
|
257
|
-
defaultCapabilitiesError?: string;
|
|
258
|
-
/**
|
|
259
|
-
* Present only when `application` was asked for: whether the namespace now
|
|
260
|
-
* runs it. `false` leaves it with no application; retry with
|
|
261
|
-
* `govern({ groupId: namespaceId, op: targetApplicationSetOp(application) })`.
|
|
262
|
-
*/
|
|
263
|
-
applicationSet?: boolean;
|
|
264
|
-
/** Why `applicationSet` is `false`. */
|
|
265
|
-
applicationError?: string;
|
|
266
|
-
}
|
|
267
|
-
/** Where an accepted intent landed. */
|
|
268
|
-
export interface IntentResult<T = unknown> {
|
|
269
|
-
/** The context's scope root after the run — did this change anything? */
|
|
270
|
-
rootHash: string;
|
|
271
|
-
/** The method's own return value. */
|
|
272
|
-
returns: T | null;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Thrown when a relay refuses an intent, carrying which precondition failed.
|
|
276
|
-
*
|
|
277
|
-
* The distinction is the whole reason this type exists. A `403` from this
|
|
278
|
-
* endpoint means one of several unrelated things — no grant on the relay, the
|
|
279
|
-
* relay is a TEE replica (`ReadOnlyTee`) or a `ReadOnly` member (neither ever
|
|
280
|
-
* relays), the author is
|
|
281
|
-
* not a member or is read-only in the context, or the nonce was already spent
|
|
282
|
-
* — and they send a caller somewhere completely different: ask an admin, pick
|
|
283
|
-
* a relay the namespace admits in `relay` mode, ask for an invitation, or just
|
|
284
|
-
* retry. Collapsing them into "forbidden" makes a retryable replay look
|
|
285
|
-
* like a permissions bug.
|
|
286
|
-
*/
|
|
287
|
-
export declare class IntentRefusedError extends Error {
|
|
288
|
-
/** The relay's own explanation, verbatim. */
|
|
289
|
-
readonly reason: string;
|
|
290
|
-
/** `true` when re-presenting the same intent under a *fresh* warrant may work. */
|
|
291
|
-
readonly retryable: boolean;
|
|
292
|
-
readonly status: number;
|
|
293
|
-
name: string;
|
|
294
|
-
constructor(
|
|
295
|
-
/** The relay's own explanation, verbatim. */
|
|
296
|
-
reason: string,
|
|
297
|
-
/** `true` when re-presenting the same intent under a *fresh* warrant may work. */
|
|
298
|
-
retryable: boolean, status: number);
|
|
299
|
-
}
|
|
300
|
-
export declare class RelayClient {
|
|
301
|
-
private readonly baseUrl;
|
|
302
|
-
private readonly config;
|
|
303
|
-
private readonly fetchImpl;
|
|
304
|
-
private readonly timeoutMs;
|
|
305
|
-
/** How many times a 429 is waited out before it is raised. */
|
|
306
|
-
private readonly rateLimitRetries;
|
|
307
|
-
constructor(config: RelayClientConfig);
|
|
308
|
-
/**
|
|
309
|
-
* The relay's origin, trailing slash stripped.
|
|
310
|
-
*
|
|
311
|
-
* Exposed because a relay **is a node**: the same origin that answers the
|
|
312
|
-
* intents routes also answers `/auth/challenge`, `/auth/token`, `/sse` and
|
|
313
|
-
* `/ws`. Anything building an observing session over this relay needs the
|
|
314
|
-
* URL, and asking the caller to pass it a second time is how the two drift.
|
|
315
|
-
*/
|
|
316
|
-
get relayUrl(): string;
|
|
317
|
-
/** The author's account, hex — whose consent every warrant here carries. */
|
|
318
|
-
get authorAccount(): string;
|
|
319
|
-
/**
|
|
320
|
-
* The author's `AccountProof<DeviceCert>`, hex.
|
|
321
|
-
*
|
|
322
|
-
* The same credential `login()` wants, which is why it is readable: a caller
|
|
323
|
-
* that already handed it to this client should not have to hand an identical
|
|
324
|
-
* copy to the login as well, where the two could disagree.
|
|
325
|
-
*/
|
|
326
|
-
get authorProof(): string;
|
|
327
|
-
/**
|
|
328
|
-
* The author device's signer.
|
|
329
|
-
*
|
|
330
|
-
* A {@link Signer} and never the secret: this returns something that can
|
|
331
|
-
* *sign*, so no caller of a `RelayClient` gains the ability to read a key
|
|
332
|
-
* that was passed in as `deviceSecret`. That asymmetry is the point — the
|
|
333
|
-
* login needs a signature, not key material.
|
|
334
|
-
*/
|
|
335
|
-
authorSigner(): Promise<Signer>;
|
|
336
|
-
/**
|
|
337
|
-
* Ask the relay what it can do in `contextId`.
|
|
338
|
-
*
|
|
339
|
-
* Cheap and unauthenticated on a relay that serves delegated execution
|
|
340
|
-
* publicly, which is what makes it usable as a precondition check rather than
|
|
341
|
-
* as diagnostics after a failure.
|
|
342
|
-
*/
|
|
343
|
-
describe(contextId: string): Promise<RelayDescription>;
|
|
344
|
-
/**
|
|
345
|
-
* Mint a warrant for `method(args)` and present it to the relay.
|
|
346
|
-
*
|
|
347
|
-
* One intent, once: the warrant authorizes exactly this method and these
|
|
348
|
-
* arguments in exactly this context, and its nonce is spent by the network on
|
|
349
|
-
* apply. Nothing accumulates and nothing is reusable.
|
|
350
|
-
*/
|
|
351
|
-
execute<T = unknown>(contextId: string, method: string, argsJson?: unknown): Promise<IntentResult<T>>;
|
|
352
|
-
/**
|
|
353
|
-
* Publish one presence statement through the relay (`presence-intents`).
|
|
354
|
-
*
|
|
355
|
-
* Not retried on 429: presence resends every 2.5 s anyway, and a retry would
|
|
356
|
-
* only queue behind the next resend. A refusal throws with its `status`.
|
|
357
|
-
*/
|
|
358
|
-
presenceIntent(contextId: string, body: {
|
|
359
|
-
state: string | null;
|
|
360
|
-
seq: number;
|
|
361
|
-
sentAtMs: number;
|
|
362
|
-
signature: string;
|
|
363
|
-
authorProof: string;
|
|
364
|
-
}): Promise<void>;
|
|
365
|
-
/**
|
|
366
|
-
* Ask the relay what it can do about creating contexts in `groupId`.
|
|
367
|
-
*
|
|
368
|
-
* Pass `author` (an account, hex) to also learn whether that account may
|
|
369
|
-
* create here — `authorMayCreate` is present only then.
|
|
370
|
-
*/
|
|
371
|
-
describeCreation(groupId: string, opts?: {
|
|
372
|
-
author?: string;
|
|
373
|
-
}): Promise<CreationDescription>;
|
|
374
|
-
/**
|
|
375
|
-
* Create a context in a group through the relay, as the author.
|
|
376
|
-
*
|
|
377
|
-
* Always asks {@link describeCreation} first — with the author, so both
|
|
378
|
-
* standing checks happen before anything is signed. A relay without standing
|
|
379
|
-
* in the group, or an author without `CAN_CREATE_CONTEXT`, is refused here as
|
|
380
|
-
* an {@link IntentRefusedError} *before* a nonce is taken: the nonce source
|
|
381
|
-
* is monotonic, and a warrant nobody will spend burns one for nothing.
|
|
382
|
-
*
|
|
383
|
-
* The creation warrant's nonce is spent in the new context's per-device
|
|
384
|
-
* ledger — the same one later `execute` calls in that context draw from — so
|
|
385
|
-
* it comes from the configured {@link NonceSource} like any other warrant.
|
|
386
|
-
*
|
|
387
|
-
* Sealing: nothing here is plaintext-specific. The request goes through the
|
|
388
|
-
* injected `fetch`, so a `createAttestedSealedFetch` seals it exactly as it
|
|
389
|
-
* seals `execute`. Whether the relay *accepts* it sealed is the node's call:
|
|
390
|
-
* a proxy-auth relay only admits sealed requests for routes `merod` serves
|
|
391
|
-
* without a credential, so `/admin-api/groups/:id/context-intents` must be on
|
|
392
|
-
* that list on the core side or the request comes back
|
|
393
|
-
* `403 sealed_route_unguarded`.
|
|
394
|
-
*/
|
|
395
|
-
createContext(input: CreateContextInput): Promise<CreatedContext>;
|
|
396
|
-
/**
|
|
397
|
-
* Ask the relay whether it may publish governance ops for members of
|
|
398
|
-
* `groupId`, and which account and key a warrant must name.
|
|
399
|
-
*/
|
|
400
|
-
describeGovernance(groupId: string): Promise<GovernanceDescription>;
|
|
401
|
-
/**
|
|
402
|
-
* Publish one governance op through the relay, as the author.
|
|
403
|
-
*
|
|
404
|
-
* The warrant commits to the op's exact bytes and is scoped to `groupId`, so
|
|
405
|
-
* the relay can neither change what the op does nor spend it elsewhere. Every
|
|
406
|
-
* peer applies the op as the author, so the author's own rights decide
|
|
407
|
-
* (`MANAGE_MEMBERS` to add a member, `CAN_CREATE_SUBGROUP` to create a
|
|
408
|
-
* subgroup, and so on); a lack of them comes back as an
|
|
409
|
-
* {@link IntentRefusedError} from the relay.
|
|
410
|
-
*
|
|
411
|
-
* Always asks {@link describeGovernance} first and refuses *before* taking a
|
|
412
|
-
* nonce when the relay has no standing, for the reason `createContext` does.
|
|
413
|
-
* The nonce comes from the configured {@link NonceSource}; it is spent in a
|
|
414
|
-
* per-group ledger, and a monotonic source is correct for it as for every
|
|
415
|
-
* other warrant.
|
|
416
|
-
*/
|
|
417
|
-
govern(input: GovernInput): Promise<GovernResult>;
|
|
418
|
-
/**
|
|
419
|
-
* Found a namespace through the relay, with the author as its founder, owner
|
|
420
|
-
* and admin. For an account with no node, this is how it gets a namespace at
|
|
421
|
-
* all.
|
|
422
|
-
*
|
|
423
|
-
* The author signs the exact genesis (`NamespaceCreatedV2`, carrying the
|
|
424
|
-
* author's own credential and the salt) under a root-plane governance
|
|
425
|
-
* warrant scoped to the new namespace's id, which is derived from the
|
|
426
|
-
* author's account and the salt, so the relay can neither choose another id
|
|
427
|
-
* nor found it for anyone else. The relay takes an identity in the new
|
|
428
|
-
* namespace, mints its key, publishes the genesis, and is seated as the
|
|
429
|
-
* founding relay (a `Member` holding `CAN_AUTHOR_ON_BEHALF`), so later
|
|
430
|
-
* `govern`, `createContext` and `execute` calls in the namespace work
|
|
431
|
-
* through it straight away. A TEE relay then admits itself as the
|
|
432
|
-
* namespace's first TEE; `teeEnabled` reports whether it did.
|
|
433
|
-
*
|
|
434
|
-
* The executor cannot be learned from the relay first: the namespace does not
|
|
435
|
-
* exist, so `describeGovernance` has nothing to answer about. It comes from
|
|
436
|
-
* `input.executor` only, and without it this throws before taking a nonce.
|
|
437
|
-
* The nonce is spent in the new namespace's ledger.
|
|
438
|
-
*
|
|
439
|
-
* With `defaultCapabilities`, the founder then sets the namespace's default
|
|
440
|
-
* capability mask through the same relay (a second warrant, a second nonce)
|
|
441
|
-
* and `defaultCapabilitiesSet` reports whether it landed. A failure there
|
|
442
|
-
* does not throw, since the namespace is already founded.
|
|
443
|
-
*
|
|
444
|
-
* Refusals (`400`/`403`) come back as {@link IntentRefusedError}; a salt
|
|
445
|
-
* that names an existing namespace is a `409`, an `HTTPError`.
|
|
446
|
-
*/
|
|
447
|
-
foundNamespace(input: FoundNamespaceInput): Promise<FoundedNamespace>;
|
|
448
|
-
private postGovernance;
|
|
449
|
-
/**
|
|
450
|
-
* The relay's answer, checked against a configured account.
|
|
451
|
-
* Decoded here so a relay naming no key is refused before a nonce is taken.
|
|
452
|
-
*/
|
|
453
|
-
private checkedExecutor;
|
|
454
|
-
/**
|
|
455
|
-
* One request, waiting out a rate limit rather than failing the caller.
|
|
456
|
-
*
|
|
457
|
-
* The relay's ingress limits the delegated-execution routes to 20 requests a
|
|
458
|
-
* second per source IP, burst 40 — tighter than everything else it serves,
|
|
459
|
-
* because those two routes are the ones it answers to anonymous callers.
|
|
460
|
-
*
|
|
461
|
-
* Retrying a 429 is safe here in a way retrying most refusals is not: the
|
|
462
|
-
* limiter sits *first* in the middleware chain, so a throttled request never
|
|
463
|
-
* reached the node and its warrant nonce was never spent. The same bytes can
|
|
464
|
-
* go again. Contrast the spent-nonce 403 below, which needs a fresh warrant.
|
|
465
|
-
*
|
|
466
|
-
* `Retry-After` is honoured when the ingress sends one; otherwise the wait
|
|
467
|
-
* doubles from a little over the limiter's own window, which is the shortest
|
|
468
|
-
* delay that can actually clear.
|
|
469
|
-
*/
|
|
470
|
-
private json;
|
|
471
|
-
private jsonOnce;
|
|
472
|
-
}
|