@calimero-network/mero-js 26.4.1 → 26.6.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/index.d.ts +4 -2
- package/dist/account/index.js +2 -1
- package/dist/account/relay-login-error.d.ts +32 -0
- package/dist/account/relay-login-error.js +34 -0
- package/dist/account/session.d.ts +34 -2
- package/dist/account/session.js +64 -19
- package/dist/admin-api/redeem-invitation.js +6 -0
- package/dist/errors/classify.js +9 -13
- package/dist/http-client/index.d.ts +1 -1
- package/dist/http-client/index.js +1 -1
- package/dist/http-client/web-client.d.ts +13 -0
- package/dist/http-client/web-client.js +20 -1
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +87 -10
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +87 -10
- package/dist/index.mjs.map +4 -4
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -28,8 +28,8 @@ export { signerFromSecret, signerFromCryptoKey } from "./signer/index.js";
|
|
|
28
28
|
export type { Signer } from "./signer/index.js";
|
|
29
29
|
export { generateAccountRoot, accountRootFromPhrase, accountRootFromSecret, createAccountRootSigner, accountRootSignerFromPhrase, signAccountLink, signAccountLogin, resolveRoot, resolveRootPair, } from "./account/index.js";
|
|
30
30
|
export type { AccountRoot, RecoverableAccountRoot, AccountRootSigner, NewAccountRootSigner, AccountLinkInput, AccountLoginInput, RootSource, ResolvedRoot, } from "./account/index.js";
|
|
31
|
-
export { readDelegatedSession, saveDelegatedSession, clearDelegatedSession, readDelegatedCredential, saveDelegatedCredential, clearDelegatedCredential, persistedNonces, markContextNonceSpent, pinRelayNodeKey, readPinnedRelayNodeKey, attemptRelayNodeKey, resolveRelayNodeKey, learnRelayNodeKey, RELAY_NODE_KEY_RETRY_MS, forgetMethodKinds, forgetRelaySealing, relayTransportFetch, buildDelegatedClient, readRelayMap, rememberRelay, relayForContext, carryExecutorAccount, knownRelays, listDelegatedContexts, listDelegatedNamespaces, resolveRelayFromInvitation, normaliseAccount, joinWithNode, bootstrapFromInvitation, joinAsAccount, createDelegatedContext, createDelegatedPrivateContext, foundDelegatedNamespace, delegatedGovernance, latestPublishedVersion, HA_ACCOUNT_NOT_LINKED_MESSAGE, HA_REFUSAL_MESSAGES, governGroup, governRoot, namespaceOfGroup, rememberGroupNamespace, applicationIdForBundle, fetchRegistryBundles, resolveApplicationIdFromRegistry, selectLatestBundle, createAccountAdmin, InvitationNotClaimableError, NoRelayError, NotForAccountError, createNodeAdmin, } from "./account/index.js";
|
|
32
|
-
export type { DelegatedCredential, DelegatedAccountSession, RelayMap, RelayNodeKeyAttempt, RelayResolutionStep, RelayResolutionFailure, ResolvedInvitationRelay, ResolveRelayResult, ResolveRelayFromInvitationInput, JoinWithNodeInput, JoinWithNodeResult, JoinWithNodeSuccess, JoinWithNodeFailure, JoinWithNodeStep, BootstrapStep, BootstrapResult, BootstrapSuccess, BootstrapFailure, BootstrapFromInvitationInput, CreateDelegatedContextRequest, FoundedDelegatedNamespace, RegistryBundle, ResolvedApplication, AccountAdminDeps, NodeAdminDeps, } from "./account/index.js";
|
|
31
|
+
export { readDelegatedSession, saveDelegatedSession, clearDelegatedSession, readDelegatedCredential, saveDelegatedCredential, clearDelegatedCredential, persistedNonces, markContextNonceSpent, pinRelayNodeKey, readPinnedRelayNodeKey, attemptRelayNodeKey, resolveRelayNodeKey, learnRelayNodeKey, RELAY_NODE_KEY_RETRY_MS, forgetMethodKinds, forgetRelaySealing, relayTransportFetch, buildDelegatedClient, readRelayMap, rememberRelay, relayForContext, carryExecutorAccount, knownRelays, listDelegatedContexts, listDelegatedNamespaces, RelaysUnavailableError, resolveRelayFromInvitation, normaliseAccount, joinWithNode, bootstrapFromInvitation, joinAsAccount, createDelegatedContext, createDelegatedPrivateContext, foundDelegatedNamespace, delegatedGovernance, latestPublishedVersion, HA_ACCOUNT_NOT_LINKED_MESSAGE, HA_REFUSAL_MESSAGES, governGroup, governRoot, namespaceOfGroup, rememberGroupNamespace, applicationIdForBundle, fetchRegistryBundles, resolveApplicationIdFromRegistry, selectLatestBundle, createAccountAdmin, InvitationNotClaimableError, NoRelayError, NotForAccountError, RelayLoginError, createNodeAdmin, } from "./account/index.js";
|
|
32
|
+
export type { DelegatedCredential, DelegatedAccountSession, RelayMap, RelayNodeKeyAttempt, RelayLoginFailureKind, RelayListingFailure, RelayResolutionStep, RelayResolutionFailure, ResolvedInvitationRelay, ResolveRelayResult, ResolveRelayFromInvitationInput, JoinWithNodeInput, JoinWithNodeResult, JoinWithNodeSuccess, JoinWithNodeFailure, JoinWithNodeStep, BootstrapStep, BootstrapResult, BootstrapSuccess, BootstrapFailure, BootstrapFromInvitationInput, CreateDelegatedContextRequest, FoundedDelegatedNamespace, RegistryBundle, ResolvedApplication, AccountAdminDeps, NodeAdminDeps, } from "./account/index.js";
|
|
33
33
|
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, accountForRootPublicKey, parseDeviceCredential, verifyDeviceCredential, } from "./device-cert/index.js";
|
|
34
34
|
export type { DeviceCertInput, DeviceCredential } from "./device-cert/index.js";
|
|
35
35
|
export { signDeviceScope, deviceScopePayload } from "./device-cert/index.js";
|
package/dist/index.js
CHANGED
|
@@ -52,7 +52,7 @@ resolveRoot, resolveRootPair, } from "./account/index.js";
|
|
|
52
52
|
// Framework-free; mero-react re-exports every one of these under the same name
|
|
53
53
|
// (its `DelegatedSession` is `DelegatedAccountSession` here: the login module
|
|
54
54
|
// already owns the bare name for the session `login()` mints).
|
|
55
|
-
export { readDelegatedSession, saveDelegatedSession, clearDelegatedSession, readDelegatedCredential, saveDelegatedCredential, clearDelegatedCredential, persistedNonces, markContextNonceSpent, pinRelayNodeKey, readPinnedRelayNodeKey, attemptRelayNodeKey, resolveRelayNodeKey, learnRelayNodeKey, RELAY_NODE_KEY_RETRY_MS, forgetMethodKinds, forgetRelaySealing, relayTransportFetch, buildDelegatedClient, readRelayMap, rememberRelay, relayForContext, carryExecutorAccount, knownRelays, listDelegatedContexts, listDelegatedNamespaces, resolveRelayFromInvitation, normaliseAccount, joinWithNode, bootstrapFromInvitation, joinAsAccount, createDelegatedContext, createDelegatedPrivateContext, foundDelegatedNamespace, delegatedGovernance, latestPublishedVersion, HA_ACCOUNT_NOT_LINKED_MESSAGE, HA_REFUSAL_MESSAGES, governGroup, governRoot, namespaceOfGroup, rememberGroupNamespace, applicationIdForBundle, fetchRegistryBundles, resolveApplicationIdFromRegistry, selectLatestBundle, createAccountAdmin, InvitationNotClaimableError, NoRelayError, NotForAccountError, createNodeAdmin, } from "./account/index.js";
|
|
55
|
+
export { readDelegatedSession, saveDelegatedSession, clearDelegatedSession, readDelegatedCredential, saveDelegatedCredential, clearDelegatedCredential, persistedNonces, markContextNonceSpent, pinRelayNodeKey, readPinnedRelayNodeKey, attemptRelayNodeKey, resolveRelayNodeKey, learnRelayNodeKey, RELAY_NODE_KEY_RETRY_MS, forgetMethodKinds, forgetRelaySealing, relayTransportFetch, buildDelegatedClient, readRelayMap, rememberRelay, relayForContext, carryExecutorAccount, knownRelays, listDelegatedContexts, listDelegatedNamespaces, RelaysUnavailableError, resolveRelayFromInvitation, normaliseAccount, joinWithNode, bootstrapFromInvitation, joinAsAccount, createDelegatedContext, createDelegatedPrivateContext, foundDelegatedNamespace, delegatedGovernance, latestPublishedVersion, HA_ACCOUNT_NOT_LINKED_MESSAGE, HA_REFUSAL_MESSAGES, governGroup, governRoot, namespaceOfGroup, rememberGroupNamespace, applicationIdForBundle, fetchRegistryBundles, resolveApplicationIdFromRegistry, selectLatestBundle, createAccountAdmin, InvitationNotClaimableError, NoRelayError, NotForAccountError, RelayLoginError, createNodeAdmin, } from "./account/index.js";
|
|
56
56
|
export { signDeviceCert, mintDeviceId, deviceCertPayload, accountForRoot, accountForRootPublicKey, parseDeviceCredential, verifyDeviceCredential, } from "./device-cert/index.js";
|
|
57
57
|
// A device's scope — signed by the root beside its certificate, and what a relay
|
|
58
58
|
// needs with it to bind the device of an account that has no node.
|
package/dist/index.mjs
CHANGED
|
@@ -317,6 +317,12 @@ var AuthRevokedError = class extends HTTPError {
|
|
|
317
317
|
this.message = `Authentication revoked (${reason}): HTTP ${status} ${statusText}`;
|
|
318
318
|
}
|
|
319
319
|
};
|
|
320
|
+
var RequestAuthError = class extends Error {
|
|
321
|
+
constructor() {
|
|
322
|
+
super(...arguments);
|
|
323
|
+
this.name = "RequestAuthError";
|
|
324
|
+
}
|
|
325
|
+
};
|
|
320
326
|
function headersToRecord(headers) {
|
|
321
327
|
const record = {};
|
|
322
328
|
headers.forEach((value, key) => {
|
|
@@ -644,6 +650,7 @@ var WebHttpClient = class {
|
|
|
644
650
|
headers.Authorization = `Bearer ${token}`;
|
|
645
651
|
}
|
|
646
652
|
} catch (error) {
|
|
653
|
+
if (error instanceof RequestAuthError) throw error;
|
|
647
654
|
}
|
|
648
655
|
}
|
|
649
656
|
if (initHeaders) {
|
|
@@ -1079,6 +1086,30 @@ function withoutCap(mask, cap) {
|
|
|
1079
1086
|
return (mask & ~cap) >>> 0;
|
|
1080
1087
|
}
|
|
1081
1088
|
|
|
1089
|
+
// src/account/relay-login-error.ts
|
|
1090
|
+
var RelayLoginError = class extends RequestAuthError {
|
|
1091
|
+
constructor(relayUrl, cause) {
|
|
1092
|
+
const kind = relayLoginFailureKind(cause);
|
|
1093
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
1094
|
+
super(
|
|
1095
|
+
kind === "signed-out" ? `the relay ${relayUrl} refused this device's credential (${detail}); sign in again` : `could not log in to the relay ${relayUrl}: ${detail}`
|
|
1096
|
+
);
|
|
1097
|
+
this.name = "RelayLoginError";
|
|
1098
|
+
this.cause = cause;
|
|
1099
|
+
this.relayUrl = relayUrl;
|
|
1100
|
+
this.kind = kind;
|
|
1101
|
+
this.loginStatus = loginStatusOf(cause);
|
|
1102
|
+
}
|
|
1103
|
+
};
|
|
1104
|
+
function relayLoginFailureKind(cause) {
|
|
1105
|
+
const status = loginStatusOf(cause);
|
|
1106
|
+
return status === 401 || status === 403 ? "signed-out" : "unavailable";
|
|
1107
|
+
}
|
|
1108
|
+
function loginStatusOf(cause) {
|
|
1109
|
+
const status = cause?.status;
|
|
1110
|
+
return typeof status === "number" && Number.isFinite(status) ? status : void 0;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1082
1113
|
// src/errors/classify.ts
|
|
1083
1114
|
var RETRYABLE = {
|
|
1084
1115
|
invalid: false,
|
|
@@ -1149,6 +1180,11 @@ function messageOf(err, fallback = "Request failed") {
|
|
|
1149
1180
|
return fallback;
|
|
1150
1181
|
}
|
|
1151
1182
|
function classifyError(err) {
|
|
1183
|
+
if (err instanceof RelayLoginError) {
|
|
1184
|
+
const status2 = err.loginStatus;
|
|
1185
|
+
const kind2 = err.kind === "signed-out" ? "unauthorized" : status2 ? kindForStatus(status2) : "unreachable";
|
|
1186
|
+
return { kind: kind2, status: status2, retryable: RETRYABLE[kind2], message: messageOf(err) };
|
|
1187
|
+
}
|
|
1152
1188
|
const status = statusOf(err);
|
|
1153
1189
|
let kind;
|
|
1154
1190
|
if (status !== void 0) {
|
|
@@ -1203,6 +1239,9 @@ function reasonFromMessage(message) {
|
|
|
1203
1239
|
}
|
|
1204
1240
|
var FINAL_FROM_TEXT = /* @__PURE__ */ new Set(["already-used", "removed"]);
|
|
1205
1241
|
function classifyJoinFailure(err, message) {
|
|
1242
|
+
if (err instanceof RelayLoginError) {
|
|
1243
|
+
return { reason: err.kind === "signed-out" ? "signed-out" : "node-unreachable", retryable: true };
|
|
1244
|
+
}
|
|
1206
1245
|
const { kind, status } = classifyError(err);
|
|
1207
1246
|
const fromText = reasonFromMessage(message);
|
|
1208
1247
|
const code = refusalCodeOf(err);
|
|
@@ -9406,9 +9445,8 @@ function relaySession(s, nodeKey) {
|
|
|
9406
9445
|
token = minted.accessToken;
|
|
9407
9446
|
return token;
|
|
9408
9447
|
}).catch((e) => {
|
|
9409
|
-
console.warn("[mero-js] relay login failed", e);
|
|
9410
9448
|
token = null;
|
|
9411
|
-
|
|
9449
|
+
throw new RelayLoginError(s.relayUrl, e);
|
|
9412
9450
|
}).finally(() => {
|
|
9413
9451
|
inflight = null;
|
|
9414
9452
|
});
|
|
@@ -9570,24 +9608,53 @@ function knownRelays(s) {
|
|
|
9570
9608
|
const all = [s.relayUrl, ...Object.values(map.namespaces), ...Object.values(map.contexts)].filter((u) => typeof u === "string" && u.length > 0).map(relayOrigin);
|
|
9571
9609
|
return [...new Set(all)];
|
|
9572
9610
|
}
|
|
9611
|
+
var RelaysUnavailableError = class extends Error {
|
|
9612
|
+
constructor(failures) {
|
|
9613
|
+
super(`none of this account's relays answered: ${failures.map((f) => `${f.relayUrl} (${f.kind})`).join(", ")}`);
|
|
9614
|
+
this.failures = failures;
|
|
9615
|
+
this.name = "RelaysUnavailableError";
|
|
9616
|
+
this.relays = failures.map((f) => f.relayUrl);
|
|
9617
|
+
}
|
|
9618
|
+
/** Every relay refused its attestation: retrying will not help. */
|
|
9619
|
+
get refused() {
|
|
9620
|
+
return this.failures.every((f) => f.kind === "refused");
|
|
9621
|
+
}
|
|
9622
|
+
};
|
|
9623
|
+
async function listingClient(s, relayUrl) {
|
|
9624
|
+
const key = await attemptRelayNodeKey(relayUrl);
|
|
9625
|
+
if (key.kind !== "learned") {
|
|
9626
|
+
console.warn("[mero-js] could not learn the relay node key from its attestation", key.error);
|
|
9627
|
+
return { failure: { relayUrl, kind: key.kind, error: key.error } };
|
|
9628
|
+
}
|
|
9629
|
+
const client2 = buildDelegatedClient({ ...s, relayUrl }, null);
|
|
9630
|
+
if (!client2) return { failure: { relayUrl, kind: "unavailable", error: new Error(`no client for ${relayUrl}`) } };
|
|
9631
|
+
return { client: client2 };
|
|
9632
|
+
}
|
|
9573
9633
|
async function listDelegatedContexts(s) {
|
|
9574
9634
|
const out = [];
|
|
9575
9635
|
const map = readRelayMap(s.account);
|
|
9576
|
-
|
|
9636
|
+
const relays = knownRelays(s);
|
|
9637
|
+
const failures = [];
|
|
9638
|
+
for (const relayUrl of relays) {
|
|
9639
|
+
const got = await listingClient(s, relayUrl);
|
|
9640
|
+
if ("failure" in got) {
|
|
9641
|
+
failures.push(got.failure);
|
|
9642
|
+
continue;
|
|
9643
|
+
}
|
|
9644
|
+
const { client: client2 } = got;
|
|
9577
9645
|
try {
|
|
9578
|
-
if (!await resolveRelayNodeKey(relayUrl)) continue;
|
|
9579
|
-
const client2 = buildDelegatedClient({ ...s, relayUrl }, null);
|
|
9580
|
-
if (!client2) continue;
|
|
9581
9646
|
const { contexts } = await client2.admin.getContexts();
|
|
9582
9647
|
for (const c of contexts ?? []) {
|
|
9583
9648
|
out.push({ ...c, relayUrl });
|
|
9584
9649
|
map.contexts[c.id] = relayUrl;
|
|
9585
9650
|
}
|
|
9586
9651
|
} catch (e) {
|
|
9652
|
+
failures.push({ relayUrl, kind: "unavailable", error: e });
|
|
9587
9653
|
console.warn(`[mero-js] could not list contexts on ${relayUrl}`, e);
|
|
9588
9654
|
}
|
|
9589
9655
|
}
|
|
9590
9656
|
writeRelayMap(s.account, map);
|
|
9657
|
+
if (relays.length > 0 && failures.length === relays.length) throw new RelaysUnavailableError(failures);
|
|
9591
9658
|
return out;
|
|
9592
9659
|
}
|
|
9593
9660
|
async function listDelegatedNamespaces(s) {
|
|
@@ -9595,11 +9662,16 @@ async function listDelegatedNamespaces(s) {
|
|
|
9595
9662
|
const out = [];
|
|
9596
9663
|
const seen = /* @__PURE__ */ new Set();
|
|
9597
9664
|
const map = readRelayMap(s.account);
|
|
9598
|
-
|
|
9665
|
+
const relays = knownRelays(s);
|
|
9666
|
+
const failures = [];
|
|
9667
|
+
for (const relayUrl of relays) {
|
|
9668
|
+
const got = await listingClient(s, relayUrl);
|
|
9669
|
+
if ("failure" in got) {
|
|
9670
|
+
failures.push(got.failure);
|
|
9671
|
+
continue;
|
|
9672
|
+
}
|
|
9673
|
+
const { client: client2 } = got;
|
|
9599
9674
|
try {
|
|
9600
|
-
if (!await resolveRelayNodeKey(relayUrl)) continue;
|
|
9601
|
-
const client2 = buildDelegatedClient({ ...s, relayUrl }, null);
|
|
9602
|
-
if (!client2) continue;
|
|
9603
9675
|
for (const ns of await client2.admin.listNamespaces()) {
|
|
9604
9676
|
if (seen.has(ns.namespaceId)) continue;
|
|
9605
9677
|
seen.add(ns.namespaceId);
|
|
@@ -9607,10 +9679,12 @@ async function listDelegatedNamespaces(s) {
|
|
|
9607
9679
|
(_a = map.namespaces)[_b = ns.namespaceId] ?? (_a[_b] = relayUrl);
|
|
9608
9680
|
}
|
|
9609
9681
|
} catch (e) {
|
|
9682
|
+
failures.push({ relayUrl, kind: "unavailable", error: e });
|
|
9610
9683
|
console.warn(`[mero-js] could not list namespaces on ${relayUrl}`, e);
|
|
9611
9684
|
}
|
|
9612
9685
|
}
|
|
9613
9686
|
writeRelayMap(s.account, map);
|
|
9687
|
+
if (relays.length > 0 && failures.length === relays.length) throw new RelaysUnavailableError(failures);
|
|
9614
9688
|
return out;
|
|
9615
9689
|
}
|
|
9616
9690
|
|
|
@@ -13129,10 +13203,13 @@ export {
|
|
|
13129
13203
|
RELAY_NODE_KEY_RETRY_MS,
|
|
13130
13204
|
REQUEST_PROOF_HEADER,
|
|
13131
13205
|
RelayClient,
|
|
13206
|
+
RelayLoginError,
|
|
13132
13207
|
RelayNotDialableError,
|
|
13133
13208
|
RelayObserver,
|
|
13134
13209
|
RelayPresenceClient,
|
|
13135
13210
|
RelayTransport,
|
|
13211
|
+
RelaysUnavailableError,
|
|
13212
|
+
RequestAuthError,
|
|
13136
13213
|
RpcClient,
|
|
13137
13214
|
RpcError,
|
|
13138
13215
|
SEALED_CONTENT_TYPE,
|