@calimero-network/mero-js 25.3.2 → 26.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/dist/account/session.d.ts +3 -6
- package/dist/account/session.js +3 -6
- package/dist/admin-api/admin-client.d.ts +2 -133
- package/dist/admin-api/admin-client.js +1 -226
- package/dist/admin-api/admin-types.d.ts +0 -146
- package/dist/events/sse.d.ts +8 -0
- package/dist/events/sse.js +19 -8
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +19 -270
- package/dist/index.cjs.map +2 -2
- package/dist/index.mjs +19 -270
- package/dist/index.mjs.map +2 -2
- package/dist/relay/index.d.ts +2 -2
- package/dist/relay/index.js +1 -1
- package/dist/relay/nonce-source.d.ts +4 -127
- package/dist/relay/nonce-source.js +2 -154
- package/dist/relay/relay-client.d.ts +3 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -82,8 +82,6 @@ __export(index_exports, {
|
|
|
82
82
|
SseClient: () => SseClient,
|
|
83
83
|
StaleTransportKeyError: () => StaleTransportKeyError,
|
|
84
84
|
UnknownRelayError: () => UnknownRelayError,
|
|
85
|
-
WarrantNonceExhaustedError: () => WarrantNonceExhaustedError,
|
|
86
|
-
WarrantNonceRouteUnavailableError: () => WarrantNonceRouteUnavailableError,
|
|
87
85
|
WebHttpClient: () => WebHttpClient,
|
|
88
86
|
WsClient: () => WsClient,
|
|
89
87
|
accountForRoot: () => accountForRoot,
|
|
@@ -100,7 +98,6 @@ __export(index_exports, {
|
|
|
100
98
|
attestAgent: () => attestAgent,
|
|
101
99
|
attestKeyBinding: () => attestKeyBinding,
|
|
102
100
|
attestRelayNodeKey: () => attestRelayNodeKey,
|
|
103
|
-
authorNonceLookup: () => authorNonceLookup,
|
|
104
101
|
beginCloudLink: () => beginCloudLink,
|
|
105
102
|
beginDeviceEnrolment: () => beginDeviceEnrolment,
|
|
106
103
|
bootstrapFromInvitation: () => bootstrapFromInvitation,
|
|
@@ -151,7 +148,6 @@ __export(index_exports, {
|
|
|
151
148
|
createProofAuthorizer: () => createProofAuthorizer,
|
|
152
149
|
createProofSigner: () => createProofSigner,
|
|
153
150
|
createQuoteVerifier: () => createQuoteVerifier,
|
|
154
|
-
createRecoveringNonceSource: () => createRecoveringNonceSource,
|
|
155
151
|
createRetryableMethod: () => createRetryableMethod,
|
|
156
152
|
createSealedFetch: () => createSealedFetch,
|
|
157
153
|
createSignedReleaseSealedFetch: () => createSignedReleaseSealedFetch,
|
|
@@ -225,7 +221,6 @@ __export(index_exports, {
|
|
|
225
221
|
parseCreationWarrant: () => parseCreationWarrant,
|
|
226
222
|
parseDeviceCredential: () => parseDeviceCredential,
|
|
227
223
|
parseGovernanceWarrant: () => parseGovernanceWarrant,
|
|
228
|
-
parseWarrantNonce: () => parseWarrantNonce,
|
|
229
224
|
persistedNonces: () => persistedNonces,
|
|
230
225
|
pinRelayNodeKey: () => pinRelayNodeKey,
|
|
231
226
|
presenceStatementBytes: () => presenceStatementBytes,
|
|
@@ -1519,50 +1514,6 @@ async function redeemInvitation(parsed, redeemer) {
|
|
|
1519
1514
|
}
|
|
1520
1515
|
|
|
1521
1516
|
// src/admin-api/admin-client.ts
|
|
1522
|
-
var WarrantNonceRouteUnavailableError = class extends Error {
|
|
1523
|
-
constructor(path, cause) {
|
|
1524
|
-
super(
|
|
1525
|
-
`this node does not serve warrant-nonce discovery (404 on ${path}); it predates the route, so a client must fall back to its own nonce counter`
|
|
1526
|
-
);
|
|
1527
|
-
this.path = path;
|
|
1528
|
-
this.cause = cause;
|
|
1529
|
-
this.name = "WarrantNonceRouteUnavailableError";
|
|
1530
|
-
}
|
|
1531
|
-
};
|
|
1532
|
-
function u64FromBody(body, parsed, field) {
|
|
1533
|
-
const value = parsed[field];
|
|
1534
|
-
if (value === void 0 || value === null) return void 0;
|
|
1535
|
-
const digits = new RegExp(`"${field}"\\s*:\\s*(\\d+)`).exec(body);
|
|
1536
|
-
if (digits) return BigInt(digits[1]);
|
|
1537
|
-
if (typeof value === "string" && /^\d+$/.test(value)) return BigInt(value);
|
|
1538
|
-
throw new Error(`warrant-nonce response field \`${field}\` is not a u64: ${JSON.stringify(value)}`);
|
|
1539
|
-
}
|
|
1540
|
-
function parseWarrantNonce(body) {
|
|
1541
|
-
const parsed = JSON.parse(body);
|
|
1542
|
-
const data = parsed?.data;
|
|
1543
|
-
if (!data || typeof data !== "object") {
|
|
1544
|
-
throw new Error(`warrant-nonce response had no \`data\`: ${body.slice(0, 200)}`);
|
|
1545
|
-
}
|
|
1546
|
-
const common = {
|
|
1547
|
-
contextId: String(data.contextId ?? ""),
|
|
1548
|
-
authorDeviceKey: String(data.authorDeviceKey ?? ""),
|
|
1549
|
-
seen: data.seen === true,
|
|
1550
|
-
highWaterNonce: u64FromBody(body, data, "highWaterNonce"),
|
|
1551
|
-
// Not defaulted: a node that stopped sending it is a node whose window this
|
|
1552
|
-
// client would be guessing at, and the window is not a nonce input anyway.
|
|
1553
|
-
windowWidth: u64FromBody(body, data, "windowWidth") ?? 0n
|
|
1554
|
-
};
|
|
1555
|
-
const nextNonce = u64FromBody(body, data, "nextNonce");
|
|
1556
|
-
if (nextNonce === void 0) {
|
|
1557
|
-
return {
|
|
1558
|
-
...common,
|
|
1559
|
-
kind: "exhausted",
|
|
1560
|
-
seen: true,
|
|
1561
|
-
highWaterNonce: common.highWaterNonce ?? 0xffffffffffffffffn
|
|
1562
|
-
};
|
|
1563
|
-
}
|
|
1564
|
-
return { ...common, kind: "open", nextNonce };
|
|
1565
|
-
}
|
|
1566
1517
|
function unwrap(response) {
|
|
1567
1518
|
return response?.data;
|
|
1568
1519
|
}
|
|
@@ -1776,14 +1727,6 @@ var AdminApiClient = class {
|
|
|
1776
1727
|
);
|
|
1777
1728
|
return r ?? { contextId, resyncStarted: true };
|
|
1778
1729
|
}
|
|
1779
|
-
async inviteSpecializedNode(request) {
|
|
1780
|
-
return unwrap(
|
|
1781
|
-
await this.httpClient.post(
|
|
1782
|
-
"/admin-api/contexts/invite-specialized-node",
|
|
1783
|
-
request
|
|
1784
|
-
)
|
|
1785
|
-
);
|
|
1786
|
-
}
|
|
1787
1730
|
async updateContextApplication(contextId, request) {
|
|
1788
1731
|
await this.httpClient.post(`/admin-api/contexts/${pathSegment(contextId)}/application`, request);
|
|
1789
1732
|
}
|
|
@@ -1975,29 +1918,6 @@ var AdminApiClient = class {
|
|
|
1975
1918
|
async getNodeIdentity() {
|
|
1976
1919
|
return unwrap(await this.httpClient.get("/admin-api/identity"));
|
|
1977
1920
|
}
|
|
1978
|
-
/**
|
|
1979
|
-
* @deprecated Use {@link getNodeIdentity} instead. Every field this returns is
|
|
1980
|
-
* node-level, so the namespace was only ever decoration — it now delegates to
|
|
1981
|
-
* the node-level route and reshapes the answer.
|
|
1982
|
-
*
|
|
1983
|
-
* Three consequences of that delegation, all visible to a caller who relied on
|
|
1984
|
-
* the old route's behaviour:
|
|
1985
|
-
*
|
|
1986
|
-
* - **No participation gate.** The namespace route answered 404 when this node
|
|
1987
|
-
* had never joined the namespace; this answers whatever the node's identity
|
|
1988
|
-
* is, regardless. If you were using it to ask "am I in this namespace?", ask
|
|
1989
|
-
* {@link listNamespaces} instead — that is the question you were really
|
|
1990
|
-
* asking.
|
|
1991
|
-
* - **`namespaceId` is echoed verbatim.** The old route resolved a subgroup id
|
|
1992
|
-
* to its root namespace and returned that; passing a subgroup id here gives
|
|
1993
|
-
* the subgroup id back.
|
|
1994
|
-
* - **404 means something else.** Previously "not my namespace", now "this node
|
|
1995
|
-
* holds no account root yet".
|
|
1996
|
-
*/
|
|
1997
|
-
async getNamespaceIdentity(namespaceId) {
|
|
1998
|
-
const node = await this.getNodeIdentity();
|
|
1999
|
-
return { namespaceId, publicKey: node.publicKey, account: node.accountId };
|
|
2000
|
-
}
|
|
2001
1921
|
/**
|
|
2002
1922
|
* Ask this node to run one method on a member's behalf, under a warrant that
|
|
2003
1923
|
* member signed.
|
|
@@ -2471,104 +2391,6 @@ var AdminApiClient = class {
|
|
|
2471
2391
|
);
|
|
2472
2392
|
return response.members;
|
|
2473
2393
|
}
|
|
2474
|
-
/**
|
|
2475
|
-
* Where `authorDeviceKey` stands in its warrant-nonce sequence in `contextId`.
|
|
2476
|
-
*
|
|
2477
|
-
* # What this is for
|
|
2478
|
-
*
|
|
2479
|
-
* The nonce is the one input to a warrant that is stateful on the *client*.
|
|
2480
|
-
* Everything else an author needs it either holds (its keys, the method, the
|
|
2481
|
-
* args) or can read from the relay ({@link RelayClient.describe} gives the
|
|
2482
|
-
* executor account and the grant). So an author that has lost its counter —
|
|
2483
|
-
* a browser keyholder in partitioned or periodically cleared storage, which
|
|
2484
|
-
* is its normal lifecycle rather than a fault — otherwise has exactly one
|
|
2485
|
-
* strategy: guess upward and burn a refused round trip per wrong guess, with
|
|
2486
|
-
* each refusal indistinguishable at the API from a genuinely spent nonce.
|
|
2487
|
-
*
|
|
2488
|
-
* Read {@link WarrantNonceOpen.nextNonce} and mint there. If you still hold
|
|
2489
|
-
* your own counter, mint at `max(ownNext, nextNonce)`: nonce state folds per
|
|
2490
|
-
* peer, so a node can only be BEHIND a client whose warrants it has not
|
|
2491
|
-
* applied — never ahead of the truth. An author spread across several relays
|
|
2492
|
-
* asks each and takes the highest answer. {@link createRecoveringNonceSource}
|
|
2493
|
-
* does all of that.
|
|
2494
|
-
*
|
|
2495
|
-
* Purely a read. It spends nothing and advances nothing, so it may be called
|
|
2496
|
-
* as often as you like.
|
|
2497
|
-
*
|
|
2498
|
-
* # Forward compatibility — this route is NEW
|
|
2499
|
-
*
|
|
2500
|
-
* It is not on core `master` yet, so a current node answers **404**, which
|
|
2501
|
-
* this method surfaces as {@link WarrantNonceRouteUnavailableError} rather
|
|
2502
|
-
* than as an opaque {@link HTTPError}. That distinction matters because the
|
|
2503
|
-
* handler itself never 404s: a device with no row is a `200` with
|
|
2504
|
-
* `seen: false`, and a malformed id is a `400`. So a 404 here means the node
|
|
2505
|
-
* does not serve the route at all — an older build, or a deployment that has
|
|
2506
|
-
* not re-mounted it — and the answer is to fall back to a local counter, not
|
|
2507
|
-
* to retry.
|
|
2508
|
-
*
|
|
2509
|
-
* # Authentication
|
|
2510
|
-
*
|
|
2511
|
-
* On the PROTECTED admin router, unlike the two delegated-execution routes it
|
|
2512
|
-
* sits beside: it takes another principal's device key as input and reports
|
|
2513
|
-
* that principal's activity. A `--public-intents` deployment does not serve
|
|
2514
|
-
* this anonymously, so an admin credential is required.
|
|
2515
|
-
*
|
|
2516
|
-
* @param authorDeviceKey the device's signing key, base58 (43-44 chars) or
|
|
2517
|
-
* hex (exactly 64). The node accepts either; the two never collide.
|
|
2518
|
-
*/
|
|
2519
|
-
async getWarrantNonce(contextId, authorDeviceKey) {
|
|
2520
|
-
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce/${pathSegment(authorDeviceKey)}`;
|
|
2521
|
-
let raw;
|
|
2522
|
-
try {
|
|
2523
|
-
raw = await this.httpClient.get(path, { parse: "text" });
|
|
2524
|
-
} catch (error) {
|
|
2525
|
-
if (error instanceof HTTPError && error.status === 404) {
|
|
2526
|
-
throw new WarrantNonceRouteUnavailableError(path, error);
|
|
2527
|
-
}
|
|
2528
|
-
throw error;
|
|
2529
|
-
}
|
|
2530
|
-
return parseWarrantNonce(raw);
|
|
2531
|
-
}
|
|
2532
|
-
/**
|
|
2533
|
-
* The same answer, asked for the way a delegated client has to ask.
|
|
2534
|
-
*
|
|
2535
|
-
* {@link getWarrantNonce} is on the protected admin router, so a keyholder
|
|
2536
|
-
* writing through a relay — the client this whole facility exists for — is
|
|
2537
|
-
* refused it: measured `403` for a session carrying exactly
|
|
2538
|
-
* `context:intent`, `context:query`, `context:subscribe`. That client has no
|
|
2539
|
-
* admin credential and cannot be given one without defeating the point of the
|
|
2540
|
-
* delegated surface.
|
|
2541
|
-
*
|
|
2542
|
-
* What it does have is the credential proving the device is its own, which it
|
|
2543
|
-
* already sends on every write. Presenting it here makes the request
|
|
2544
|
-
* self-scoped: you learn a device's position only by proving, at call time,
|
|
2545
|
-
* that the device is yours. So there is no oracle to protect against, and no
|
|
2546
|
-
* reason for an admin gate.
|
|
2547
|
-
*
|
|
2548
|
-
* The device key is NOT a parameter. It is read from the verified
|
|
2549
|
-
* certificate server-side, which is the only reading that cannot disagree
|
|
2550
|
-
* with the signature — a key supplied alongside would be a second spelling of
|
|
2551
|
-
* the same fact, and two spellings can differ.
|
|
2552
|
-
*
|
|
2553
|
-
* Returns the identical shape {@link getWarrantNonce} returns, so a caller can
|
|
2554
|
-
* swap one for the other without touching what it does with the answer.
|
|
2555
|
-
*
|
|
2556
|
-
* @param authorProof hex-encoded borsh `AccountProof<DeviceCert>` — the same
|
|
2557
|
-
* value passed as `authorProof` to the relay client.
|
|
2558
|
-
*/
|
|
2559
|
-
async getWarrantNonceAsAuthor(contextId, authorProof) {
|
|
2560
|
-
const path = `/admin-api/contexts/${pathSegment(contextId)}/warrant-nonce`;
|
|
2561
|
-
let raw;
|
|
2562
|
-
try {
|
|
2563
|
-
raw = await this.httpClient.post(path, { authorProof }, { parse: "text" });
|
|
2564
|
-
} catch (error) {
|
|
2565
|
-
if (error instanceof HTTPError && error.status === 404) {
|
|
2566
|
-
throw new WarrantNonceRouteUnavailableError(path, error);
|
|
2567
|
-
}
|
|
2568
|
-
throw error;
|
|
2569
|
-
}
|
|
2570
|
-
return parseWarrantNonce(raw);
|
|
2571
|
-
}
|
|
2572
2394
|
/**
|
|
2573
2395
|
* Member accounts in the group and the devices bound to each. An admin node
|
|
2574
2396
|
* sees every account; a plain member only its own. `403` if this node is not a
|
|
@@ -2891,15 +2713,6 @@ var AdminApiClient = class {
|
|
|
2891
2713
|
async teeAttest(request) {
|
|
2892
2714
|
return unwrap(await this.httpClient.post("/admin-api/tee/attest", request));
|
|
2893
2715
|
}
|
|
2894
|
-
/**
|
|
2895
|
-
* @deprecated Nodes no longer serve `/admin-api/tee/verify-quote` (removed in
|
|
2896
|
-
* core#3262), so this fails. Verify quotes with `createQuoteVerifier`.
|
|
2897
|
-
*/
|
|
2898
|
-
async teeVerifyQuote(request) {
|
|
2899
|
-
return unwrap(
|
|
2900
|
-
await this.httpClient.post("/admin-api/tee/verify-quote", request)
|
|
2901
|
-
);
|
|
2902
|
-
}
|
|
2903
2716
|
// ---- Network ----
|
|
2904
2717
|
async getPeersCount() {
|
|
2905
2718
|
return this.httpClient.get("/admin-api/peers");
|
|
@@ -3328,7 +3141,8 @@ var SseClient = class {
|
|
|
3328
3141
|
return;
|
|
3329
3142
|
}
|
|
3330
3143
|
this.closed = false;
|
|
3331
|
-
|
|
3144
|
+
const controller = new AbortController();
|
|
3145
|
+
this.abortController = controller;
|
|
3332
3146
|
try {
|
|
3333
3147
|
const url2 = `${this.baseUrl}/sse`;
|
|
3334
3148
|
const headers = {
|
|
@@ -3338,7 +3152,7 @@ var SseClient = class {
|
|
|
3338
3152
|
const proofAttached = carriesProof(headers);
|
|
3339
3153
|
const response = await this.fetchImpl(url2, {
|
|
3340
3154
|
headers,
|
|
3341
|
-
signal:
|
|
3155
|
+
signal: controller.signal,
|
|
3342
3156
|
...proofAttached && { redirect: "manual" }
|
|
3343
3157
|
});
|
|
3344
3158
|
if (proofAttached) refuseProofRedirect(response, url2);
|
|
@@ -3366,21 +3180,31 @@ var SseClient = class {
|
|
|
3366
3180
|
if (!response.body) {
|
|
3367
3181
|
throw new Error("SSE response has no body");
|
|
3368
3182
|
}
|
|
3369
|
-
this.readStream(response.body).catch((err) => {
|
|
3370
|
-
if (this.
|
|
3183
|
+
this.readStream(response.body, controller).catch((err) => {
|
|
3184
|
+
if (this.superseded(controller)) return;
|
|
3371
3185
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
3372
3186
|
this.emit("error", error);
|
|
3373
3187
|
this.scheduleReconnect();
|
|
3374
3188
|
});
|
|
3375
3189
|
} catch (err) {
|
|
3376
|
-
if (this.
|
|
3190
|
+
if (this.superseded(controller)) return;
|
|
3377
3191
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
3378
3192
|
this.emit("error", error);
|
|
3379
3193
|
if (error instanceof AuthRevokedError) return;
|
|
3380
3194
|
this.scheduleReconnect();
|
|
3381
3195
|
}
|
|
3382
3196
|
}
|
|
3383
|
-
|
|
3197
|
+
/**
|
|
3198
|
+
* Whether `controller`'s connection is no longer the one this client holds:
|
|
3199
|
+
* closed, or replaced by a later connect. Its abort lands asynchronously,
|
|
3200
|
+
* after a `close()` + `connect()` has already cleared `closed`, so `closed`
|
|
3201
|
+
* alone cannot tell; reporting it, and reconnecting for it, would abort the
|
|
3202
|
+
* live connection, whose own abort would do the same, without end.
|
|
3203
|
+
*/
|
|
3204
|
+
superseded(controller) {
|
|
3205
|
+
return this.closed || controller.signal.aborted || this.abortController !== controller;
|
|
3206
|
+
}
|
|
3207
|
+
async readStream(body, controller) {
|
|
3384
3208
|
const reader = body.getReader();
|
|
3385
3209
|
const decoder = new TextDecoder();
|
|
3386
3210
|
let buffer = "";
|
|
@@ -3408,11 +3232,11 @@ var SseClient = class {
|
|
|
3408
3232
|
}
|
|
3409
3233
|
}
|
|
3410
3234
|
} catch (err) {
|
|
3411
|
-
if (this.
|
|
3235
|
+
if (this.superseded(controller)) return;
|
|
3412
3236
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
3413
3237
|
this.emit("error", error);
|
|
3414
3238
|
}
|
|
3415
|
-
if (!this.
|
|
3239
|
+
if (!this.superseded(controller)) {
|
|
3416
3240
|
this.scheduleReconnect();
|
|
3417
3241
|
}
|
|
3418
3242
|
}
|
|
@@ -10072,81 +9896,6 @@ function createLocalStorageNonceSource(key, storage) {
|
|
|
10072
9896
|
}
|
|
10073
9897
|
};
|
|
10074
9898
|
}
|
|
10075
|
-
function authorNonceLookup(options) {
|
|
10076
|
-
return {
|
|
10077
|
-
getWarrantNonce: (contextId, _authorDeviceKey) => options.client.getWarrantNonceAsAuthor(contextId, options.authorProof)
|
|
10078
|
-
};
|
|
10079
|
-
}
|
|
10080
|
-
var WarrantNonceExhaustedError = class extends Error {
|
|
10081
|
-
constructor(contextId, authorDeviceKey) {
|
|
10082
|
-
super(
|
|
10083
|
-
`author device ${authorDeviceKey} has spent every nonce in context ${contextId}; it must re-key to write again`
|
|
10084
|
-
);
|
|
10085
|
-
this.contextId = contextId;
|
|
10086
|
-
this.authorDeviceKey = authorDeviceKey;
|
|
10087
|
-
this.name = "WarrantNonceExhaustedError";
|
|
10088
|
-
}
|
|
10089
|
-
};
|
|
10090
|
-
function createRecoveringNonceSource(options) {
|
|
10091
|
-
const lookups = Array.isArray(options.lookups) ? options.lookups : [options.lookups];
|
|
10092
|
-
if (lookups.length === 0) {
|
|
10093
|
-
throw new Error("a recovering nonce source needs at least one node to ask");
|
|
10094
|
-
}
|
|
10095
|
-
const local = options.local ?? createMemoryNonceSource(1);
|
|
10096
|
-
const onLookupFailure = options.onLookupFailure ?? "throw";
|
|
10097
|
-
let floor = null;
|
|
10098
|
-
let pending = null;
|
|
10099
|
-
const resolveFloor = async () => {
|
|
10100
|
-
const answers = await Promise.allSettled(
|
|
10101
|
-
lookups.map(
|
|
10102
|
-
(lookup) => lookup.getWarrantNonce(options.contextId, options.authorDeviceKey)
|
|
10103
|
-
)
|
|
10104
|
-
);
|
|
10105
|
-
let highest = null;
|
|
10106
|
-
let exhausted = false;
|
|
10107
|
-
for (const answer of answers) {
|
|
10108
|
-
if (answer.status !== "fulfilled") continue;
|
|
10109
|
-
const state = answer.value;
|
|
10110
|
-
if (state.kind === "exhausted") {
|
|
10111
|
-
exhausted = true;
|
|
10112
|
-
continue;
|
|
10113
|
-
}
|
|
10114
|
-
if (highest === null || state.nextNonce > highest) highest = state.nextNonce;
|
|
10115
|
-
}
|
|
10116
|
-
if (highest === null && exhausted) {
|
|
10117
|
-
throw new WarrantNonceExhaustedError(options.contextId, options.authorDeviceKey);
|
|
10118
|
-
}
|
|
10119
|
-
if (highest === null) {
|
|
10120
|
-
const first = answers.find((a) => a.status === "rejected");
|
|
10121
|
-
const reason = first && first.status === "rejected" ? first.reason : void 0;
|
|
10122
|
-
if (onLookupFailure === "local") {
|
|
10123
|
-
floor = 0n;
|
|
10124
|
-
return;
|
|
10125
|
-
}
|
|
10126
|
-
throw reason instanceof Error ? reason : new Error(`no node could answer where the warrant-nonce sequence stands: ${String(reason)}`);
|
|
10127
|
-
}
|
|
10128
|
-
floor = highest;
|
|
10129
|
-
await local.advanceTo?.(highest);
|
|
10130
|
-
};
|
|
10131
|
-
return {
|
|
10132
|
-
async next() {
|
|
10133
|
-
if (floor === null) {
|
|
10134
|
-
pending ?? (pending = resolveFloor().finally(() => {
|
|
10135
|
-
pending = null;
|
|
10136
|
-
}));
|
|
10137
|
-
await pending;
|
|
10138
|
-
}
|
|
10139
|
-
const mine = await local.next();
|
|
10140
|
-
const value = floor !== null && floor > mine ? floor : mine;
|
|
10141
|
-
floor = value + 1n;
|
|
10142
|
-
return value;
|
|
10143
|
-
},
|
|
10144
|
-
async advanceTo(wanted) {
|
|
10145
|
-
if (floor === null || wanted > floor) floor = wanted;
|
|
10146
|
-
await local.advanceTo?.(wanted);
|
|
10147
|
-
}
|
|
10148
|
-
};
|
|
10149
|
-
}
|
|
10150
9899
|
|
|
10151
9900
|
// src/cloud/connect.ts
|
|
10152
9901
|
async function connectCloud(options) {
|