@calimero-network/mero-js 24.6.0 → 24.7.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.js +17 -6
- package/dist/account/index.d.ts +1 -1
- package/dist/account/index.js +1 -1
- package/dist/account/session.d.ts +23 -1
- package/dist/account/session.js +96 -12
- package/dist/admin-api/admin-types.d.ts +2 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +3 -3
- package/dist/index.cjs +73 -12
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +73 -12
- package/dist/index.mjs.map +3 -3
- package/dist/transport/mero-client.d.ts +9 -0
- package/dist/transport/mero-client.js +13 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -166,6 +166,7 @@ __export(index_exports, {
|
|
|
166
166
|
fetchNodeReleaseVersion: () => fetchNodeReleaseVersion,
|
|
167
167
|
fetchRegistryBundles: () => fetchRegistryBundles,
|
|
168
168
|
forgetMethodKinds: () => forgetMethodKinds,
|
|
169
|
+
forgetRelaySealing: () => forgetRelaySealing,
|
|
169
170
|
foundDelegatedNamespace: () => foundDelegatedNamespace,
|
|
170
171
|
foundedNamespaceId: () => foundedNamespaceId,
|
|
171
172
|
generateAccountRoot: () => generateAccountRoot,
|
|
@@ -226,6 +227,7 @@ __export(index_exports, {
|
|
|
226
227
|
readRelayMap: () => readRelayMap,
|
|
227
228
|
redeemInvitation: () => redeemInvitation,
|
|
228
229
|
relayForContext: () => relayForContext,
|
|
230
|
+
relayTransportFetch: () => relayTransportFetch,
|
|
229
231
|
rememberGroupNamespace: () => rememberGroupNamespace,
|
|
230
232
|
rememberRelay: () => rememberRelay,
|
|
231
233
|
reportDataOf: () => reportDataOf,
|
|
@@ -9118,7 +9120,7 @@ function missingNodeKey(surface) {
|
|
|
9118
9120
|
`this relay-transport client cannot open ${surface}: it was given no relay node key. A relay is an ordinary node and does serve /sse and /ws \u2014 but the login statement must be signed against the node's device signing key, learned out of band (never read from the node, and never derived from its peerId). Pass it as \`observe: { nodeKey }\`. For a cloud-hosted relay the cloud does not publish it yet \u2014 see mdma #312.`
|
|
9119
9121
|
);
|
|
9120
9122
|
}
|
|
9121
|
-
function buildObserver(relay, observe) {
|
|
9123
|
+
function buildObserver(relay, observe, fetchImpl) {
|
|
9122
9124
|
const nodeKey = observe?.nodeKey;
|
|
9123
9125
|
if (!nodeKey) return null;
|
|
9124
9126
|
return new RelayObserver({
|
|
@@ -9129,7 +9131,7 @@ function buildObserver(relay, observe) {
|
|
|
9129
9131
|
signer: observe?.signer ? async () => observe.signer : () => relay.authorSigner(),
|
|
9130
9132
|
clientName: observe?.clientName,
|
|
9131
9133
|
ttlSeconds: observe?.ttlSeconds,
|
|
9132
|
-
fetch: observe?.fetch,
|
|
9134
|
+
fetch: observe?.fetch ?? fetchImpl,
|
|
9133
9135
|
timeoutMs: observe?.timeoutMs
|
|
9134
9136
|
});
|
|
9135
9137
|
}
|
|
@@ -9150,12 +9152,16 @@ var MeroClient = class {
|
|
|
9150
9152
|
this.proofAuthorizer = null;
|
|
9151
9153
|
this.relayUrl = null;
|
|
9152
9154
|
this.proofEvents = null;
|
|
9155
|
+
/** The relay transport's `fetch`, if one was given. */
|
|
9156
|
+
this.relayFetch = void 0;
|
|
9153
9157
|
this.relayPresence = null;
|
|
9154
9158
|
if (config.transport === "relay") {
|
|
9155
9159
|
this.transport = "relay";
|
|
9156
9160
|
this.nodeClient = null;
|
|
9157
|
-
const
|
|
9158
|
-
this.
|
|
9161
|
+
const fetchImpl = config.fetch;
|
|
9162
|
+
this.relayFetch = fetchImpl;
|
|
9163
|
+
const relay = config.relay instanceof RelayClient ? config.relay : new RelayClient({ ...config.relay, fetch: config.relay.fetch ?? fetchImpl });
|
|
9164
|
+
this.relayObserver = buildObserver(relay, config.observe, fetchImpl);
|
|
9159
9165
|
this.rpcTransport = new RelayTransport(relay, this.relayObserver);
|
|
9160
9166
|
this.relayUrl = relay.relayUrl;
|
|
9161
9167
|
if (config.proof) {
|
|
@@ -9165,13 +9171,14 @@ var MeroClient = class {
|
|
|
9165
9171
|
const token = config.session;
|
|
9166
9172
|
this.relayAdmin = createAdminApiClient({
|
|
9167
9173
|
baseUrl: relay.relayUrl,
|
|
9168
|
-
getAuthToken: typeof token === "string" ? async () => token : token
|
|
9174
|
+
getAuthToken: typeof token === "string" ? async () => token : token,
|
|
9175
|
+
fetch: fetchImpl
|
|
9169
9176
|
});
|
|
9170
9177
|
} else if (this.proofAuthorizer) {
|
|
9171
9178
|
const authorizeRequest = this.proofAuthorizer;
|
|
9172
9179
|
this.relayAdmin = createAdminApiClientFromHttpClient(
|
|
9173
9180
|
createHttpClient({
|
|
9174
|
-
fetch: (url, init) => globalThis.fetch(url, init),
|
|
9181
|
+
fetch: (url, init) => fetchImpl ? fetchImpl(url, init) : globalThis.fetch(url, init),
|
|
9175
9182
|
baseUrl: relay.relayUrl,
|
|
9176
9183
|
authorizeRequest
|
|
9177
9184
|
}),
|
|
@@ -9285,7 +9292,8 @@ var MeroClient = class {
|
|
|
9285
9292
|
if (this.proofAuthorizer && this.relayUrl) {
|
|
9286
9293
|
this.proofEvents ?? (this.proofEvents = new SseClient({
|
|
9287
9294
|
baseUrl: this.relayUrl,
|
|
9288
|
-
authorize: this.proofAuthorizer
|
|
9295
|
+
authorize: this.proofAuthorizer,
|
|
9296
|
+
fetch: this.relayFetch
|
|
9289
9297
|
}));
|
|
9290
9298
|
return this.proofEvents;
|
|
9291
9299
|
}
|
|
@@ -9535,8 +9543,8 @@ function relayQuoteVerifier(relayUrl, fetchRelay) {
|
|
|
9535
9543
|
};
|
|
9536
9544
|
return Object.assign(verify, { includeCollateral: true });
|
|
9537
9545
|
}
|
|
9538
|
-
async function attemptRelayNodeKey(relayUrl) {
|
|
9539
|
-
const pinned = readPinnedRelayNodeKey(relayUrl);
|
|
9546
|
+
async function attemptRelayNodeKey(relayUrl, options = {}) {
|
|
9547
|
+
const pinned = options.fresh ? null : readPinnedRelayNodeKey(relayUrl);
|
|
9540
9548
|
if (pinned) return { kind: "learned", nodeKey: pinned };
|
|
9541
9549
|
const marked = { failure: null };
|
|
9542
9550
|
const fetchRelay = relayFetch(marked);
|
|
@@ -9600,6 +9608,54 @@ function jwtExpiryMs2(token) {
|
|
|
9600
9608
|
return null;
|
|
9601
9609
|
}
|
|
9602
9610
|
}
|
|
9611
|
+
var sealedFetches = /* @__PURE__ */ new Map();
|
|
9612
|
+
function forgetRelaySealing() {
|
|
9613
|
+
sealedFetches.clear();
|
|
9614
|
+
}
|
|
9615
|
+
async function isUnguardedRefusal(response) {
|
|
9616
|
+
if (response.status !== 403) return false;
|
|
9617
|
+
try {
|
|
9618
|
+
const body = await response.clone().json();
|
|
9619
|
+
return body.error?.code === "sealed_route_unguarded";
|
|
9620
|
+
} catch {
|
|
9621
|
+
return false;
|
|
9622
|
+
}
|
|
9623
|
+
}
|
|
9624
|
+
function needsSession(request) {
|
|
9625
|
+
return request.headers.has("authorization") || new URL(request.url).pathname.startsWith("/auth/");
|
|
9626
|
+
}
|
|
9627
|
+
function sealedRelayFetch(relayUrl) {
|
|
9628
|
+
const plain = (input, init) => globalThis.fetch(input, init);
|
|
9629
|
+
const sealed = createAttestedSealedFetch({
|
|
9630
|
+
baseUrl: relayUrl,
|
|
9631
|
+
verify: relayQuoteVerifier(relayUrl, plain),
|
|
9632
|
+
fetch: plain
|
|
9633
|
+
});
|
|
9634
|
+
let unguarded = false;
|
|
9635
|
+
return async (input, init) => {
|
|
9636
|
+
const request = new Request(input, init);
|
|
9637
|
+
if (unguarded && needsSession(request)) return plain(request);
|
|
9638
|
+
const response = await sealed(request.clone());
|
|
9639
|
+
if (!await isUnguardedRefusal(response)) return response;
|
|
9640
|
+
if (!unguarded) {
|
|
9641
|
+
unguarded = true;
|
|
9642
|
+
console.warn(
|
|
9643
|
+
`[mero-js] ${relayOrigin(relayUrl)} cannot guard logged-in calls sealed (no forward_auth); they go over its TLS until it does`
|
|
9644
|
+
);
|
|
9645
|
+
}
|
|
9646
|
+
return plain(request);
|
|
9647
|
+
};
|
|
9648
|
+
}
|
|
9649
|
+
function relayTransportFetch(relayUrl) {
|
|
9650
|
+
if (isLoopback(relayUrl)) return void 0;
|
|
9651
|
+
const origin2 = relayOrigin(relayUrl);
|
|
9652
|
+
let found = sealedFetches.get(origin2);
|
|
9653
|
+
if (!found) {
|
|
9654
|
+
found = sealedRelayFetch(relayUrl);
|
|
9655
|
+
sealedFetches.set(origin2, found);
|
|
9656
|
+
}
|
|
9657
|
+
return found;
|
|
9658
|
+
}
|
|
9603
9659
|
function relaySession(s, nodeKey) {
|
|
9604
9660
|
let token = null;
|
|
9605
9661
|
let inflight = null;
|
|
@@ -9609,6 +9665,8 @@ function relaySession(s, nodeKey) {
|
|
|
9609
9665
|
if (!inflight) {
|
|
9610
9666
|
inflight = login({
|
|
9611
9667
|
nodeUrl: s.relayUrl,
|
|
9668
|
+
// Sealed: the token is the session, and the TLS ends outside the TD.
|
|
9669
|
+
fetch: relayTransportFetch(s.relayUrl),
|
|
9612
9670
|
node: nodeKey,
|
|
9613
9671
|
deviceSecret: s.deviceSecret,
|
|
9614
9672
|
accountProof: s.credential,
|
|
@@ -9704,6 +9762,9 @@ function buildDelegatedClient(s, _contextId) {
|
|
|
9704
9762
|
const nodeKey = readPinnedRelayNodeKey(s.relayUrl);
|
|
9705
9763
|
const client2 = createMeroClient({
|
|
9706
9764
|
transport: "relay",
|
|
9765
|
+
// Every request sealed to the relay's attested TD: intents, admin reads,
|
|
9766
|
+
// queries, the login and events (see `relayTransportFetch`).
|
|
9767
|
+
fetch: relayTransportFetch(s.relayUrl),
|
|
9707
9768
|
relay: {
|
|
9708
9769
|
relayUrl: s.relayUrl,
|
|
9709
9770
|
authorAccount: s.account,
|
|
@@ -10793,7 +10854,7 @@ function client(s, relayUrl, nonces, fetch2) {
|
|
|
10793
10854
|
authorProof: s.credential,
|
|
10794
10855
|
deviceSecret: s.deviceSecret,
|
|
10795
10856
|
nonces,
|
|
10796
|
-
fetch: fetch2
|
|
10857
|
+
fetch: fetch2 ?? relayTransportFetch(relayUrl)
|
|
10797
10858
|
});
|
|
10798
10859
|
}
|
|
10799
10860
|
async function createDelegatedContext(s, req, deps = {}) {
|
|
@@ -10880,10 +10941,10 @@ async function foundingExecutor(s, relay, fetch2) {
|
|
|
10880
10941
|
return { executorAccount: described.executorAccount, executorKey };
|
|
10881
10942
|
}
|
|
10882
10943
|
async function attestedNodeKey(relay) {
|
|
10883
|
-
const key = await attemptRelayNodeKey(relay);
|
|
10944
|
+
const key = await attemptRelayNodeKey(relay, { fresh: true });
|
|
10884
10945
|
if (key.kind === "learned") return key.nodeKey;
|
|
10885
10946
|
throw new Error(
|
|
10886
|
-
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
|
|
10947
|
+
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: it is not a signed locked-read-only release"
|
|
10887
10948
|
);
|
|
10888
10949
|
}
|
|
10889
10950
|
var HA_ACCOUNT_NOT_LINKED_MESSAGE = "link this account to your cloud user in the wallet so invitees can find this namespace";
|