@calimero-network/mero-js 19.15.0 → 19.17.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/crypto/internal.d.ts +11 -0
- package/dist/crypto/internal.js +21 -0
- package/dist/http-client/http-factory.d.ts +3 -0
- package/dist/http-client/http-factory.js +2 -0
- package/dist/http-client/http-types.d.ts +15 -0
- package/dist/http-client/web-client.js +37 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +223 -143
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +223 -143
- package/dist/index.mjs.map +3 -3
- package/dist/mero-js.d.ts +35 -0
- package/dist/mero-js.js +18 -0
- package/dist/request/caller-proof.d.ts +43 -0
- package/dist/request/caller-proof.js +36 -0
- package/dist/request/index.d.ts +2 -0
- package/dist/request/index.js +2 -0
- package/dist/request/proof-signer.d.ts +49 -0
- package/dist/request/proof-signer.js +59 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -42,6 +42,7 @@ __export(index_exports, {
|
|
|
42
42
|
accountRootFromPhrase: () => accountRootFromPhrase,
|
|
43
43
|
accountRootFromSecret: () => accountRootFromSecret,
|
|
44
44
|
buildAuthLoginUrl: () => buildAuthLoginUrl,
|
|
45
|
+
callerProof: () => callerProof,
|
|
45
46
|
combineSignals: () => combineSignals,
|
|
46
47
|
compareSemver: () => compareSemver,
|
|
47
48
|
connectCloud: () => connectCloud,
|
|
@@ -59,6 +60,7 @@ __export(index_exports, {
|
|
|
59
60
|
createNodeAdminApiClient: () => createNodeAdminApiClient,
|
|
60
61
|
createNodeAuthApiClient: () => createNodeAuthApiClient,
|
|
61
62
|
createNodeHttpClient: () => createNodeHttpClient,
|
|
63
|
+
createProofSigner: () => createProofSigner,
|
|
62
64
|
createRetryableMethod: () => createRetryableMethod,
|
|
63
65
|
createTimeoutSignal: () => createTimeoutSignal,
|
|
64
66
|
createUniversalHttpClient: () => createUniversalHttpClient,
|
|
@@ -180,6 +182,14 @@ function headersToRecord(headers) {
|
|
|
180
182
|
});
|
|
181
183
|
return record;
|
|
182
184
|
}
|
|
185
|
+
function pathForProof(url) {
|
|
186
|
+
try {
|
|
187
|
+
return new URL(url).pathname;
|
|
188
|
+
} catch {
|
|
189
|
+
const query = url.indexOf("?");
|
|
190
|
+
return query === -1 ? url : url.slice(0, query);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
183
193
|
var WebHttpClient = class {
|
|
184
194
|
constructor(transport) {
|
|
185
195
|
this.transport = transport;
|
|
@@ -306,6 +316,16 @@ var WebHttpClient = class {
|
|
|
306
316
|
if (init?.keepalive !== void 0) {
|
|
307
317
|
requestInit.keepalive = init.keepalive;
|
|
308
318
|
}
|
|
319
|
+
if (this.transport.getProof) {
|
|
320
|
+
const proof = await this.transport.getProof({
|
|
321
|
+
method: requestInit.method ?? "GET",
|
|
322
|
+
path: pathForProof(url),
|
|
323
|
+
body: requestInit.body
|
|
324
|
+
});
|
|
325
|
+
if (proof) {
|
|
326
|
+
headersObj["X-Calimero-Proof"] = proof;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
309
329
|
try {
|
|
310
330
|
const response = await this.transport.fetch(url, requestInit);
|
|
311
331
|
if (!response.ok) {
|
|
@@ -502,6 +522,7 @@ function createBrowserHttpClient(options) {
|
|
|
502
522
|
fetch: (url, init) => globalThis.fetch(url, init),
|
|
503
523
|
baseUrl: options.baseUrl,
|
|
504
524
|
getAuthToken: options.getAuthToken,
|
|
525
|
+
getProof: options.getProof,
|
|
505
526
|
onTokenRefresh: options.onTokenRefresh,
|
|
506
527
|
refreshToken: options.refreshToken,
|
|
507
528
|
onAuthRevoked: options.onAuthRevoked,
|
|
@@ -528,6 +549,7 @@ function createNodeHttpClient(options) {
|
|
|
528
549
|
fetch: isDefaultFetch ? (url, init) => globalThis.fetch(url, init) : (url, init) => fetchImpl(url, init),
|
|
529
550
|
baseUrl: options.baseUrl,
|
|
530
551
|
getAuthToken: options.getAuthToken,
|
|
552
|
+
getProof: options.getProof,
|
|
531
553
|
onTokenRefresh: options.onTokenRefresh,
|
|
532
554
|
refreshToken: options.refreshToken,
|
|
533
555
|
onAuthRevoked: options.onAuthRevoked,
|
|
@@ -1988,6 +2010,196 @@ function buildAuthLoginUrl(nodeUrl, opts) {
|
|
|
1988
2010
|
return `${base}/auth/login?${params.toString()}`;
|
|
1989
2011
|
}
|
|
1990
2012
|
|
|
2013
|
+
// src/crypto/internal.ts
|
|
2014
|
+
var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
2015
|
+
48,
|
|
2016
|
+
46,
|
|
2017
|
+
2,
|
|
2018
|
+
1,
|
|
2019
|
+
0,
|
|
2020
|
+
48,
|
|
2021
|
+
5,
|
|
2022
|
+
6,
|
|
2023
|
+
3,
|
|
2024
|
+
43,
|
|
2025
|
+
101,
|
|
2026
|
+
112,
|
|
2027
|
+
4,
|
|
2028
|
+
34,
|
|
2029
|
+
4,
|
|
2030
|
+
32
|
|
2031
|
+
]);
|
|
2032
|
+
function u32le(value) {
|
|
2033
|
+
const out = new Uint8Array(4);
|
|
2034
|
+
new DataView(out.buffer).setUint32(0, value, true);
|
|
2035
|
+
return out;
|
|
2036
|
+
}
|
|
2037
|
+
function hex(bytes) {
|
|
2038
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2039
|
+
}
|
|
2040
|
+
function fromHex(value, label, expectedBytes) {
|
|
2041
|
+
const clean = value.trim();
|
|
2042
|
+
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length !== expectedBytes * 2) {
|
|
2043
|
+
throw new Error(
|
|
2044
|
+
`${label} must be ${expectedBytes * 2} hex characters, got ${clean.length}`
|
|
2045
|
+
);
|
|
2046
|
+
}
|
|
2047
|
+
const bytes = new Uint8Array(expectedBytes);
|
|
2048
|
+
for (let i = 0; i < expectedBytes; i += 1) {
|
|
2049
|
+
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
2050
|
+
}
|
|
2051
|
+
return bytes;
|
|
2052
|
+
}
|
|
2053
|
+
function fromHexUnsized(value, label) {
|
|
2054
|
+
const clean = value.trim();
|
|
2055
|
+
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length % 2 !== 0) {
|
|
2056
|
+
throw new Error(`${label} must be an even number of hex characters`);
|
|
2057
|
+
}
|
|
2058
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
2059
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
2060
|
+
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
2061
|
+
}
|
|
2062
|
+
return bytes;
|
|
2063
|
+
}
|
|
2064
|
+
function u64le(value) {
|
|
2065
|
+
const out = new Uint8Array(8);
|
|
2066
|
+
new DataView(out.buffer).setBigUint64(0, BigInt(value), true);
|
|
2067
|
+
return out;
|
|
2068
|
+
}
|
|
2069
|
+
function concat(...parts) {
|
|
2070
|
+
const out = new Uint8Array(parts.reduce((total, p) => total + p.length, 0));
|
|
2071
|
+
let offset = 0;
|
|
2072
|
+
for (const part of parts) {
|
|
2073
|
+
out.set(part, offset);
|
|
2074
|
+
offset += part.length;
|
|
2075
|
+
}
|
|
2076
|
+
return out;
|
|
2077
|
+
}
|
|
2078
|
+
async function domainHash(domain, parts) {
|
|
2079
|
+
const chunks = [u64le(domain.length), domain];
|
|
2080
|
+
for (const part of parts) {
|
|
2081
|
+
chunks.push(u64le(part.length), part);
|
|
2082
|
+
}
|
|
2083
|
+
return new Uint8Array(
|
|
2084
|
+
await crypto.subtle.digest("SHA-256", concat(...chunks))
|
|
2085
|
+
);
|
|
2086
|
+
}
|
|
2087
|
+
async function importSigningKey(secretHex) {
|
|
2088
|
+
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2089
|
+
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2090
|
+
try {
|
|
2091
|
+
return await crypto.subtle.importKey(
|
|
2092
|
+
"pkcs8",
|
|
2093
|
+
pkcs8,
|
|
2094
|
+
{ name: "Ed25519" },
|
|
2095
|
+
false,
|
|
2096
|
+
["sign"]
|
|
2097
|
+
);
|
|
2098
|
+
} catch (cause) {
|
|
2099
|
+
const detail = cause instanceof Error ? `: ${cause.message}` : "";
|
|
2100
|
+
throw new Error(
|
|
2101
|
+
"this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`" + detail
|
|
2102
|
+
);
|
|
2103
|
+
}
|
|
2104
|
+
}
|
|
2105
|
+
async function derivePublicKey(secretHex) {
|
|
2106
|
+
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2107
|
+
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2108
|
+
const key = await crypto.subtle.importKey(
|
|
2109
|
+
"pkcs8",
|
|
2110
|
+
pkcs8,
|
|
2111
|
+
{ name: "Ed25519" },
|
|
2112
|
+
true,
|
|
2113
|
+
["sign"]
|
|
2114
|
+
);
|
|
2115
|
+
const jwk = await crypto.subtle.exportKey("jwk", key);
|
|
2116
|
+
const raw = jwk.x;
|
|
2117
|
+
return Uint8Array.from(
|
|
2118
|
+
atob(raw.replace(/-/g, "+").replace(/_/g, "/")),
|
|
2119
|
+
(c) => c.charCodeAt(0)
|
|
2120
|
+
);
|
|
2121
|
+
}
|
|
2122
|
+
|
|
2123
|
+
// src/request/request-sig.ts
|
|
2124
|
+
var SIGN_DOMAIN = new TextEncoder().encode("calimero.auth.request.v1");
|
|
2125
|
+
var BODY_DOMAIN = new TextEncoder().encode("calimero.auth.request.body.v1");
|
|
2126
|
+
function borshString(value) {
|
|
2127
|
+
const bytes = new TextEncoder().encode(value);
|
|
2128
|
+
return concat(u32le(bytes.length), bytes);
|
|
2129
|
+
}
|
|
2130
|
+
async function requestBodyHash(body = new Uint8Array(0)) {
|
|
2131
|
+
const bytes = typeof body === "string" ? new TextEncoder().encode(body) : body;
|
|
2132
|
+
return domainHash(BODY_DOMAIN, [bytes]);
|
|
2133
|
+
}
|
|
2134
|
+
async function signRequest(input) {
|
|
2135
|
+
const key = await importSigningKey(input.signerSecret);
|
|
2136
|
+
const bodyHash = await requestBodyHash(input.body);
|
|
2137
|
+
const issuedAt = u64le(input.issuedAt);
|
|
2138
|
+
const expiresAt = u64le(input.expiresAt);
|
|
2139
|
+
const encoder = new TextEncoder();
|
|
2140
|
+
const preimage = await domainHash(SIGN_DOMAIN, [
|
|
2141
|
+
encoder.encode(input.method),
|
|
2142
|
+
encoder.encode(input.path),
|
|
2143
|
+
bodyHash,
|
|
2144
|
+
issuedAt,
|
|
2145
|
+
expiresAt
|
|
2146
|
+
]);
|
|
2147
|
+
const signature = new Uint8Array(
|
|
2148
|
+
await crypto.subtle.sign({ name: "Ed25519" }, key, preimage)
|
|
2149
|
+
);
|
|
2150
|
+
return hex(
|
|
2151
|
+
concat(
|
|
2152
|
+
borshString(input.method),
|
|
2153
|
+
borshString(input.path),
|
|
2154
|
+
bodyHash,
|
|
2155
|
+
issuedAt,
|
|
2156
|
+
expiresAt,
|
|
2157
|
+
signature
|
|
2158
|
+
)
|
|
2159
|
+
);
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
// src/request/caller-proof.ts
|
|
2163
|
+
function callerProof(input) {
|
|
2164
|
+
const credential = fromHexUnsized(input.credential, "credential");
|
|
2165
|
+
const request = fromHexUnsized(input.request, "request signature");
|
|
2166
|
+
const session = input.session === void 0 ? new Uint8Array([0]) : concat(new Uint8Array([1]), fromHexUnsized(input.session, "session statement"));
|
|
2167
|
+
return hex(concat(credential, session, request));
|
|
2168
|
+
}
|
|
2169
|
+
|
|
2170
|
+
// src/request/proof-signer.ts
|
|
2171
|
+
function bodyBytes(body) {
|
|
2172
|
+
if (body === void 0 || body === null) return new Uint8Array(0);
|
|
2173
|
+
if (typeof body === "string") return body;
|
|
2174
|
+
if (body instanceof Uint8Array) return body;
|
|
2175
|
+
if (body instanceof ArrayBuffer) return new Uint8Array(body);
|
|
2176
|
+
if (ArrayBuffer.isView(body)) {
|
|
2177
|
+
return new Uint8Array(body.buffer, body.byteOffset, body.byteLength);
|
|
2178
|
+
}
|
|
2179
|
+
throw new Error(
|
|
2180
|
+
`a request-carried proof cannot commit to a ${body?.constructor?.name ?? typeof body} body: pass a string or bytes, or use a session for this call`
|
|
2181
|
+
);
|
|
2182
|
+
}
|
|
2183
|
+
function createProofSigner(options) {
|
|
2184
|
+
const ttl = options.ttlSeconds ?? 120;
|
|
2185
|
+
const clock = options.now ?? (() => Math.floor(Date.now() / 1e3));
|
|
2186
|
+
return async (request) => {
|
|
2187
|
+
const issuedAt = clock();
|
|
2188
|
+
return callerProof({
|
|
2189
|
+
credential: options.credential,
|
|
2190
|
+
session: options.session,
|
|
2191
|
+
request: await signRequest({
|
|
2192
|
+
method: request.method,
|
|
2193
|
+
path: request.path,
|
|
2194
|
+
body: bodyBytes(request.body),
|
|
2195
|
+
issuedAt,
|
|
2196
|
+
expiresAt: issuedAt + ttl,
|
|
2197
|
+
signerSecret: options.signerSecret
|
|
2198
|
+
})
|
|
2199
|
+
});
|
|
2200
|
+
};
|
|
2201
|
+
}
|
|
2202
|
+
|
|
1991
2203
|
// src/rpc/index.ts
|
|
1992
2204
|
var RpcError = class extends Error {
|
|
1993
2205
|
constructor(code, message, data, type) {
|
|
@@ -2627,105 +2839,6 @@ var EphemeralClient = class {
|
|
|
2627
2839
|
}
|
|
2628
2840
|
};
|
|
2629
2841
|
|
|
2630
|
-
// src/crypto/internal.ts
|
|
2631
|
-
var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
2632
|
-
48,
|
|
2633
|
-
46,
|
|
2634
|
-
2,
|
|
2635
|
-
1,
|
|
2636
|
-
0,
|
|
2637
|
-
48,
|
|
2638
|
-
5,
|
|
2639
|
-
6,
|
|
2640
|
-
3,
|
|
2641
|
-
43,
|
|
2642
|
-
101,
|
|
2643
|
-
112,
|
|
2644
|
-
4,
|
|
2645
|
-
34,
|
|
2646
|
-
4,
|
|
2647
|
-
32
|
|
2648
|
-
]);
|
|
2649
|
-
function u32le(value) {
|
|
2650
|
-
const out = new Uint8Array(4);
|
|
2651
|
-
new DataView(out.buffer).setUint32(0, value, true);
|
|
2652
|
-
return out;
|
|
2653
|
-
}
|
|
2654
|
-
function hex(bytes) {
|
|
2655
|
-
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2656
|
-
}
|
|
2657
|
-
function fromHex(value, label, expectedBytes) {
|
|
2658
|
-
const clean = value.trim();
|
|
2659
|
-
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length !== expectedBytes * 2) {
|
|
2660
|
-
throw new Error(
|
|
2661
|
-
`${label} must be ${expectedBytes * 2} hex characters, got ${clean.length}`
|
|
2662
|
-
);
|
|
2663
|
-
}
|
|
2664
|
-
const bytes = new Uint8Array(expectedBytes);
|
|
2665
|
-
for (let i = 0; i < expectedBytes; i += 1) {
|
|
2666
|
-
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
2667
|
-
}
|
|
2668
|
-
return bytes;
|
|
2669
|
-
}
|
|
2670
|
-
function u64le(value) {
|
|
2671
|
-
const out = new Uint8Array(8);
|
|
2672
|
-
new DataView(out.buffer).setBigUint64(0, BigInt(value), true);
|
|
2673
|
-
return out;
|
|
2674
|
-
}
|
|
2675
|
-
function concat(...parts) {
|
|
2676
|
-
const out = new Uint8Array(parts.reduce((total, p) => total + p.length, 0));
|
|
2677
|
-
let offset = 0;
|
|
2678
|
-
for (const part of parts) {
|
|
2679
|
-
out.set(part, offset);
|
|
2680
|
-
offset += part.length;
|
|
2681
|
-
}
|
|
2682
|
-
return out;
|
|
2683
|
-
}
|
|
2684
|
-
async function domainHash(domain, parts) {
|
|
2685
|
-
const chunks = [u64le(domain.length), domain];
|
|
2686
|
-
for (const part of parts) {
|
|
2687
|
-
chunks.push(u64le(part.length), part);
|
|
2688
|
-
}
|
|
2689
|
-
return new Uint8Array(
|
|
2690
|
-
await crypto.subtle.digest("SHA-256", concat(...chunks))
|
|
2691
|
-
);
|
|
2692
|
-
}
|
|
2693
|
-
async function importSigningKey(secretHex) {
|
|
2694
|
-
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2695
|
-
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2696
|
-
try {
|
|
2697
|
-
return await crypto.subtle.importKey(
|
|
2698
|
-
"pkcs8",
|
|
2699
|
-
pkcs8,
|
|
2700
|
-
{ name: "Ed25519" },
|
|
2701
|
-
false,
|
|
2702
|
-
["sign"]
|
|
2703
|
-
);
|
|
2704
|
-
} catch (cause) {
|
|
2705
|
-
const detail = cause instanceof Error ? `: ${cause.message}` : "";
|
|
2706
|
-
throw new Error(
|
|
2707
|
-
"this runtime has no WebCrypto Ed25519, so a warrant cannot be signed here. Node 18.4+, Safari 17+, Firefox 129+ and Chrome 137+ have it; otherwise mint the warrant with `merod account warrant`" + detail
|
|
2708
|
-
);
|
|
2709
|
-
}
|
|
2710
|
-
}
|
|
2711
|
-
async function derivePublicKey(secretHex) {
|
|
2712
|
-
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2713
|
-
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2714
|
-
const key = await crypto.subtle.importKey(
|
|
2715
|
-
"pkcs8",
|
|
2716
|
-
pkcs8,
|
|
2717
|
-
{ name: "Ed25519" },
|
|
2718
|
-
true,
|
|
2719
|
-
["sign"]
|
|
2720
|
-
);
|
|
2721
|
-
const jwk = await crypto.subtle.exportKey("jwk", key);
|
|
2722
|
-
const raw = jwk.x;
|
|
2723
|
-
return Uint8Array.from(
|
|
2724
|
-
atob(raw.replace(/-/g, "+").replace(/_/g, "/")),
|
|
2725
|
-
(c) => c.charCodeAt(0)
|
|
2726
|
-
);
|
|
2727
|
-
}
|
|
2728
|
-
|
|
2729
2842
|
// src/device-cert/device-cert.ts
|
|
2730
2843
|
var CERT_DOMAIN = new TextEncoder().encode("calimero.device.cert.v1");
|
|
2731
2844
|
var ACCOUNT_ID_DOMAIN = new TextEncoder().encode("calimero.account.genesis.v1");
|
|
@@ -5723,6 +5836,10 @@ var CloudClient = class {
|
|
|
5723
5836
|
};
|
|
5724
5837
|
|
|
5725
5838
|
// src/mero-js.ts
|
|
5839
|
+
function resolveProofSigner(config) {
|
|
5840
|
+
if (!config) return void 0;
|
|
5841
|
+
return typeof config === "function" ? config : createProofSigner(config);
|
|
5842
|
+
}
|
|
5726
5843
|
var REFRESH_LOCK_NAME = "mero-js:token-refresh";
|
|
5727
5844
|
function getLockManager() {
|
|
5728
5845
|
const nav = globalThis.navigator;
|
|
@@ -5761,8 +5878,10 @@ var MeroJs = class {
|
|
|
5761
5878
|
this.tokenData = this.tokenStore.getTokens();
|
|
5762
5879
|
}
|
|
5763
5880
|
const isTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
|
|
5881
|
+
const getProof = resolveProofSigner(this.config.requestProof);
|
|
5764
5882
|
this.httpClient = createBrowserHttpClient({
|
|
5765
5883
|
baseUrl: this.config.baseUrl,
|
|
5884
|
+
getProof,
|
|
5766
5885
|
getAuthToken: async () => {
|
|
5767
5886
|
const token = await this.getValidToken();
|
|
5768
5887
|
return token?.access_token || "";
|
|
@@ -6116,7 +6235,7 @@ var LocalStorageTokenStore = class {
|
|
|
6116
6235
|
};
|
|
6117
6236
|
|
|
6118
6237
|
// src/warrant/warrant.ts
|
|
6119
|
-
var
|
|
6238
|
+
var SIGN_DOMAIN2 = new TextEncoder().encode("calimero.warrant.v2");
|
|
6120
6239
|
var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
|
|
6121
6240
|
var MAX_CITED_HEADS = 64;
|
|
6122
6241
|
var UNPINNED_APP = "00".repeat(32);
|
|
@@ -6141,7 +6260,7 @@ async function signWarrant(input) {
|
|
|
6141
6260
|
const commitment = await intentHash(input.method, input.argsJson);
|
|
6142
6261
|
const nonce = u64le(input.nonce);
|
|
6143
6262
|
const notAfter = u64le(input.notAfter);
|
|
6144
|
-
const preimage = await domainHash(
|
|
6263
|
+
const preimage = await domainHash(SIGN_DOMAIN2, [
|
|
6145
6264
|
context,
|
|
6146
6265
|
authorAccount,
|
|
6147
6266
|
publicKey,
|
|
@@ -6460,7 +6579,7 @@ function optionalBytes32(value, label) {
|
|
|
6460
6579
|
}
|
|
6461
6580
|
return concat(new Uint8Array([1]), new Uint8Array(value));
|
|
6462
6581
|
}
|
|
6463
|
-
function
|
|
6582
|
+
function borshString2(value) {
|
|
6464
6583
|
const bytes = new TextEncoder().encode(value);
|
|
6465
6584
|
return concat(u32le(bytes.length), bytes);
|
|
6466
6585
|
}
|
|
@@ -6484,7 +6603,7 @@ function encodeSignedInvitation(signed) {
|
|
|
6484
6603
|
// ...then the enclosing SignedGroupOpenInvitation, in declaration order.
|
|
6485
6604
|
// `inviter_account` sits between the signature and the addresses; putting it
|
|
6486
6605
|
// anywhere else still encodes 32 bytes and still verifies as nothing.
|
|
6487
|
-
|
|
6606
|
+
borshString2(signed.inviter_signature),
|
|
6488
6607
|
signed.inviter_account ? concat(new Uint8Array([1]), fromHex(signed.inviter_account, "inviter_account", 32)) : new Uint8Array([0]),
|
|
6489
6608
|
// A `Vec<String>`, so each entry is a bare borsh string. This carried an
|
|
6490
6609
|
// enum until core dropped the URL variant, and an enum writes a
|
|
@@ -6492,7 +6611,7 @@ function encodeSignedInvitation(signed) {
|
|
|
6492
6611
|
// every following byte and fail as `invalid invitation signature`, pointing
|
|
6493
6612
|
// nowhere near this line.
|
|
6494
6613
|
u32le(admitterAddrs.length),
|
|
6495
|
-
...admitterAddrs.map(
|
|
6614
|
+
...admitterAddrs.map(borshString2),
|
|
6496
6615
|
optionalBytes32(signed.application_id, "application_id"),
|
|
6497
6616
|
// Borsh order follows core's field order, where this is `bytecode_id`; the
|
|
6498
6617
|
// JSON key is `app_key`, a rename covering both directions that core pins in
|
|
@@ -6537,45 +6656,6 @@ async function signMemberJoinOp(input) {
|
|
|
6537
6656
|
return hex(concat(signable, signature, unendorsed));
|
|
6538
6657
|
}
|
|
6539
6658
|
|
|
6540
|
-
// src/request/request-sig.ts
|
|
6541
|
-
var SIGN_DOMAIN2 = new TextEncoder().encode("calimero.auth.request.v1");
|
|
6542
|
-
var BODY_DOMAIN = new TextEncoder().encode("calimero.auth.request.body.v1");
|
|
6543
|
-
function borshString2(value) {
|
|
6544
|
-
const bytes = new TextEncoder().encode(value);
|
|
6545
|
-
return concat(u32le(bytes.length), bytes);
|
|
6546
|
-
}
|
|
6547
|
-
async function requestBodyHash(body = new Uint8Array(0)) {
|
|
6548
|
-
const bytes = typeof body === "string" ? new TextEncoder().encode(body) : body;
|
|
6549
|
-
return domainHash(BODY_DOMAIN, [bytes]);
|
|
6550
|
-
}
|
|
6551
|
-
async function signRequest(input) {
|
|
6552
|
-
const key = await importSigningKey(input.signerSecret);
|
|
6553
|
-
const bodyHash = await requestBodyHash(input.body);
|
|
6554
|
-
const issuedAt = u64le(input.issuedAt);
|
|
6555
|
-
const expiresAt = u64le(input.expiresAt);
|
|
6556
|
-
const encoder = new TextEncoder();
|
|
6557
|
-
const preimage = await domainHash(SIGN_DOMAIN2, [
|
|
6558
|
-
encoder.encode(input.method),
|
|
6559
|
-
encoder.encode(input.path),
|
|
6560
|
-
bodyHash,
|
|
6561
|
-
issuedAt,
|
|
6562
|
-
expiresAt
|
|
6563
|
-
]);
|
|
6564
|
-
const signature = new Uint8Array(
|
|
6565
|
-
await crypto.subtle.sign({ name: "Ed25519" }, key, preimage)
|
|
6566
|
-
);
|
|
6567
|
-
return hex(
|
|
6568
|
-
concat(
|
|
6569
|
-
borshString2(input.method),
|
|
6570
|
-
borshString2(input.path),
|
|
6571
|
-
bodyHash,
|
|
6572
|
-
issuedAt,
|
|
6573
|
-
expiresAt,
|
|
6574
|
-
signature
|
|
6575
|
-
)
|
|
6576
|
-
);
|
|
6577
|
-
}
|
|
6578
|
-
|
|
6579
6659
|
// src/login/login.ts
|
|
6580
6660
|
var SIGN_DOMAIN3 = new TextEncoder().encode("calimero.auth.login.v1");
|
|
6581
6661
|
var AUDIENCE_TAG = {
|