@calimero-network/mero-js 22.3.0 → 22.4.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 +5 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +266 -17
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +266 -17
- package/dist/index.mjs.map +4 -4
- package/dist/relay/index.d.ts +1 -1
- package/dist/relay/relay-client.d.ts +76 -0
- package/dist/relay/relay-client.js +77 -0
- package/dist/warrant/creation-warrant.d.ts +145 -0
- package/dist/warrant/creation-warrant.js +189 -0
- package/dist/warrant/index.d.ts +2 -0
- package/dist/warrant/index.js +1 -0
- package/dist/warrant/warrant.d.ts +5 -0
- package/dist/warrant/warrant.js +5 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -79,6 +79,7 @@ __export(index_exports, {
|
|
|
79
79
|
createSignedReleaseVerifier: () => createSignedReleaseVerifier,
|
|
80
80
|
createTimeoutSignal: () => createTimeoutSignal,
|
|
81
81
|
createUniversalHttpClient: () => createUniversalHttpClient,
|
|
82
|
+
creationInitHash: () => creationInitHash,
|
|
82
83
|
deviceCertPayload: () => deviceCertPayload,
|
|
83
84
|
discoverLocalNodes: () => discoverLocalNodes,
|
|
84
85
|
encodeSignedInvitation: () => encodeSignedInvitation,
|
|
@@ -98,6 +99,7 @@ __export(index_exports, {
|
|
|
98
99
|
nodeEndpoint: () => nodeEndpoint,
|
|
99
100
|
nodeReleaseVersionFromImage: () => nodeReleaseVersionFromImage,
|
|
100
101
|
parseAuthCallback: () => parseAuthCallback,
|
|
102
|
+
parseCreationWarrant: () => parseCreationWarrant,
|
|
101
103
|
probeNodeHealth: () => probeNodeHealth,
|
|
102
104
|
redeemInvitation: () => redeemInvitation,
|
|
103
105
|
requestBodyHash: () => requestBodyHash,
|
|
@@ -105,6 +107,7 @@ __export(index_exports, {
|
|
|
105
107
|
shouldRetain: () => shouldRetain,
|
|
106
108
|
signAccountLink: () => signAccountLink,
|
|
107
109
|
signAccountLogin: () => signAccountLogin,
|
|
110
|
+
signCreationWarrant: () => signCreationWarrant,
|
|
108
111
|
signDeviceCert: () => signDeviceCert,
|
|
109
112
|
signLoginStatement: () => signLoginStatement,
|
|
110
113
|
signMemberJoinOp: () => signMemberJoinOp,
|
|
@@ -2306,11 +2309,11 @@ function u32le(value) {
|
|
|
2306
2309
|
function hex(bytes) {
|
|
2307
2310
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2308
2311
|
}
|
|
2309
|
-
function fromHex(value,
|
|
2312
|
+
function fromHex(value, label2, expectedBytes) {
|
|
2310
2313
|
const clean = value.trim();
|
|
2311
2314
|
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length !== expectedBytes * 2) {
|
|
2312
2315
|
throw new Error(
|
|
2313
|
-
`${
|
|
2316
|
+
`${label2} must be ${expectedBytes * 2} hex characters, got ${clean.length}`
|
|
2314
2317
|
);
|
|
2315
2318
|
}
|
|
2316
2319
|
const bytes = new Uint8Array(expectedBytes);
|
|
@@ -2319,10 +2322,10 @@ function fromHex(value, label, expectedBytes) {
|
|
|
2319
2322
|
}
|
|
2320
2323
|
return bytes;
|
|
2321
2324
|
}
|
|
2322
|
-
function fromHexUnsized(value,
|
|
2325
|
+
function fromHexUnsized(value, label2) {
|
|
2323
2326
|
const clean = value.trim();
|
|
2324
2327
|
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length % 2 !== 0) {
|
|
2325
|
-
throw new Error(`${
|
|
2328
|
+
throw new Error(`${label2} must be an even number of hex characters`);
|
|
2326
2329
|
}
|
|
2327
2330
|
const bytes = new Uint8Array(clean.length / 2);
|
|
2328
2331
|
for (let i = 0; i < bytes.length; i += 1) {
|
|
@@ -6636,14 +6639,172 @@ async function signWarrant(input) {
|
|
|
6636
6639
|
)
|
|
6637
6640
|
);
|
|
6638
6641
|
}
|
|
6639
|
-
function citedHeads(heads,
|
|
6642
|
+
function citedHeads(heads, label2) {
|
|
6640
6643
|
const list = heads ?? [];
|
|
6641
6644
|
if (list.length > MAX_CITED_HEADS) {
|
|
6642
6645
|
throw new Error(
|
|
6643
|
-
`${
|
|
6646
|
+
`${label2} cites ${list.length} heads, over the ${MAX_CITED_HEADS} a node accepts`
|
|
6644
6647
|
);
|
|
6645
6648
|
}
|
|
6646
|
-
return list.map((head, i) => fromHex(head, `${
|
|
6649
|
+
return list.map((head, i) => fromHex(head, `${label2}[${i}]`, 32));
|
|
6650
|
+
}
|
|
6651
|
+
|
|
6652
|
+
// src/warrant/creation-warrant.ts
|
|
6653
|
+
var SIGN_DOMAIN3 = new TextEncoder().encode("calimero.context-creation-warrant.v1");
|
|
6654
|
+
var INIT_DOMAIN = new TextEncoder().encode("calimero.context-creation.init.v1");
|
|
6655
|
+
var MAX_LABEL_BYTES = 256;
|
|
6656
|
+
async function creationInitHash(initArgs) {
|
|
6657
|
+
const bytes = new TextEncoder().encode(JSON.stringify(initArgs));
|
|
6658
|
+
return domainHash(INIT_DOMAIN, [bytes]);
|
|
6659
|
+
}
|
|
6660
|
+
async function creationWarrantPreimage(p) {
|
|
6661
|
+
return domainHash(SIGN_DOMAIN3, [
|
|
6662
|
+
p.group,
|
|
6663
|
+
p.seed,
|
|
6664
|
+
p.authorAccount,
|
|
6665
|
+
p.deviceKey,
|
|
6666
|
+
p.executor,
|
|
6667
|
+
p.applicationId,
|
|
6668
|
+
new Uint8Array([p.serviceName === null ? 0 : 1]),
|
|
6669
|
+
p.serviceName ?? new Uint8Array(0),
|
|
6670
|
+
new Uint8Array([p.name === null ? 0 : 1]),
|
|
6671
|
+
p.name ?? new Uint8Array(0),
|
|
6672
|
+
p.initHash,
|
|
6673
|
+
u64le(p.accountHeads.length),
|
|
6674
|
+
...p.accountHeads,
|
|
6675
|
+
u64le(p.governanceFloor.length),
|
|
6676
|
+
...p.governanceFloor,
|
|
6677
|
+
u64le(p.nonce),
|
|
6678
|
+
u64le(p.notAfter)
|
|
6679
|
+
]);
|
|
6680
|
+
}
|
|
6681
|
+
async function signCreationWarrant(input) {
|
|
6682
|
+
const group = fromHex(input.group, "group", 32);
|
|
6683
|
+
const seed = input.seed === void 0 ? crypto.getRandomValues(new Uint8Array(32)) : fromHex(input.seed, "seed", 32);
|
|
6684
|
+
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
6685
|
+
const executor = fromHex(input.executor, "executor", 32);
|
|
6686
|
+
const applicationId = fromHex(input.applicationId, "applicationId", 32);
|
|
6687
|
+
const serviceName = label(input.serviceName, "serviceName");
|
|
6688
|
+
const name = label(input.name, "name");
|
|
6689
|
+
const accountHeads = citedHeads(input.accountHeads, "accountHeads");
|
|
6690
|
+
const governanceFloor = citedHeads(input.governanceFloor, "governanceFloor");
|
|
6691
|
+
const key = await importSigningKey(input.deviceSecret);
|
|
6692
|
+
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
6693
|
+
const initHash = await creationInitHash(input.initArgs);
|
|
6694
|
+
const preimage = await creationWarrantPreimage({
|
|
6695
|
+
group,
|
|
6696
|
+
seed,
|
|
6697
|
+
authorAccount,
|
|
6698
|
+
deviceKey,
|
|
6699
|
+
executor,
|
|
6700
|
+
applicationId,
|
|
6701
|
+
serviceName,
|
|
6702
|
+
name,
|
|
6703
|
+
initHash,
|
|
6704
|
+
accountHeads,
|
|
6705
|
+
governanceFloor,
|
|
6706
|
+
nonce: input.nonce,
|
|
6707
|
+
notAfter: input.notAfter
|
|
6708
|
+
});
|
|
6709
|
+
const signature = new Uint8Array(
|
|
6710
|
+
await crypto.subtle.sign({ name: "Ed25519" }, key, preimage)
|
|
6711
|
+
);
|
|
6712
|
+
const warrant = hex(
|
|
6713
|
+
concat(
|
|
6714
|
+
group,
|
|
6715
|
+
seed,
|
|
6716
|
+
authorAccount,
|
|
6717
|
+
deviceKey,
|
|
6718
|
+
executor,
|
|
6719
|
+
applicationId,
|
|
6720
|
+
borshOption(serviceName),
|
|
6721
|
+
borshOption(name),
|
|
6722
|
+
initHash,
|
|
6723
|
+
u32le(accountHeads.length),
|
|
6724
|
+
...accountHeads,
|
|
6725
|
+
u32le(governanceFloor.length),
|
|
6726
|
+
...governanceFloor,
|
|
6727
|
+
u64le(input.nonce),
|
|
6728
|
+
u64le(input.notAfter),
|
|
6729
|
+
signature
|
|
6730
|
+
)
|
|
6731
|
+
);
|
|
6732
|
+
return { warrant, seed: hex(seed) };
|
|
6733
|
+
}
|
|
6734
|
+
function parseCreationWarrant(warrant) {
|
|
6735
|
+
const clean = warrant.trim();
|
|
6736
|
+
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length % 2 !== 0) {
|
|
6737
|
+
throw new Error("creation warrant must be an even number of hex characters");
|
|
6738
|
+
}
|
|
6739
|
+
const bytes = new Uint8Array(clean.length / 2);
|
|
6740
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
6741
|
+
bytes[i] = Number.parseInt(clean.slice(i * 2, i * 2 + 2), 16);
|
|
6742
|
+
}
|
|
6743
|
+
const view = new DataView(bytes.buffer);
|
|
6744
|
+
let o = 0;
|
|
6745
|
+
const take = (n, what) => {
|
|
6746
|
+
if (o + n > bytes.length) {
|
|
6747
|
+
throw new Error(`creation warrant ends inside ${what} (${bytes.length} bytes)`);
|
|
6748
|
+
}
|
|
6749
|
+
const out = bytes.subarray(o, o + n);
|
|
6750
|
+
o += n;
|
|
6751
|
+
return out;
|
|
6752
|
+
};
|
|
6753
|
+
const u32 = (what) => view.getUint32(take(4, what).byteOffset, true);
|
|
6754
|
+
const u64 = (what) => view.getBigUint64(take(8, what).byteOffset, true);
|
|
6755
|
+
const option = (what) => {
|
|
6756
|
+
const tag = take(1, what)[0];
|
|
6757
|
+
if (tag === 0) return null;
|
|
6758
|
+
if (tag !== 1) throw new Error(`${what} has option tag ${tag}, expected 0 or 1`);
|
|
6759
|
+
const len = u32(what);
|
|
6760
|
+
if (len > MAX_LABEL_BYTES) {
|
|
6761
|
+
throw new Error(`${what} is ${len} bytes, over the ${MAX_LABEL_BYTES} a node accepts`);
|
|
6762
|
+
}
|
|
6763
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(take(len, what));
|
|
6764
|
+
};
|
|
6765
|
+
const heads = (what) => {
|
|
6766
|
+
const count = u32(what);
|
|
6767
|
+
if (count > 64) {
|
|
6768
|
+
throw new Error(`${what} cites ${count} heads, over the 64 a node accepts`);
|
|
6769
|
+
}
|
|
6770
|
+
return Array.from({ length: count }, () => hex(take(32, what)));
|
|
6771
|
+
};
|
|
6772
|
+
const fields = {
|
|
6773
|
+
group: hex(take(32, "group")),
|
|
6774
|
+
seed: hex(take(32, "seed")),
|
|
6775
|
+
authorAccount: hex(take(32, "authorAccount")),
|
|
6776
|
+
deviceKey: hex(take(32, "deviceKey")),
|
|
6777
|
+
executor: hex(take(32, "executor")),
|
|
6778
|
+
applicationId: hex(take(32, "applicationId")),
|
|
6779
|
+
serviceName: option("serviceName"),
|
|
6780
|
+
name: option("name"),
|
|
6781
|
+
initHash: hex(take(32, "initHash")),
|
|
6782
|
+
accountHeads: heads("accountHeads"),
|
|
6783
|
+
governanceFloor: heads("governanceFloor"),
|
|
6784
|
+
nonce: u64("nonce"),
|
|
6785
|
+
notAfter: u64("notAfter"),
|
|
6786
|
+
signature: hex(take(64, "signature"))
|
|
6787
|
+
};
|
|
6788
|
+
if (o !== bytes.length) {
|
|
6789
|
+
throw new Error(
|
|
6790
|
+
`creation warrant is ${bytes.length} bytes but its fields account for ${o}`
|
|
6791
|
+
);
|
|
6792
|
+
}
|
|
6793
|
+
return fields;
|
|
6794
|
+
}
|
|
6795
|
+
function label(value, what) {
|
|
6796
|
+
if (value === void 0) return null;
|
|
6797
|
+
const bytes = new TextEncoder().encode(value);
|
|
6798
|
+
if (bytes.length > MAX_LABEL_BYTES) {
|
|
6799
|
+
throw new Error(
|
|
6800
|
+
`${what} is ${bytes.length} UTF-8 bytes, over the ${MAX_LABEL_BYTES} a node accepts`
|
|
6801
|
+
);
|
|
6802
|
+
}
|
|
6803
|
+
return bytes;
|
|
6804
|
+
}
|
|
6805
|
+
function borshOption(bytes) {
|
|
6806
|
+
if (bytes === null) return new Uint8Array([0]);
|
|
6807
|
+
return concat(new Uint8Array([1]), u32le(bytes.length), bytes);
|
|
6647
6808
|
}
|
|
6648
6809
|
|
|
6649
6810
|
// src/relay/relay-client.ts
|
|
@@ -6706,6 +6867,94 @@ var RelayClient = class {
|
|
|
6706
6867
|
);
|
|
6707
6868
|
return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
|
|
6708
6869
|
}
|
|
6870
|
+
/**
|
|
6871
|
+
* Ask the relay what it can do about creating contexts in `groupId`.
|
|
6872
|
+
*
|
|
6873
|
+
* Pass `author` (an account, hex) to also learn whether that account may
|
|
6874
|
+
* create here — `authorMayCreate` is present only then.
|
|
6875
|
+
*/
|
|
6876
|
+
async describeCreation(groupId, opts = {}) {
|
|
6877
|
+
const query = opts.author ? `?author=${encodeURIComponent(opts.author)}` : "";
|
|
6878
|
+
const body = await this.json(
|
|
6879
|
+
"GET",
|
|
6880
|
+
`/admin-api/groups/${encodeURIComponent(groupId)}/context-intents${query}`
|
|
6881
|
+
);
|
|
6882
|
+
return body.data;
|
|
6883
|
+
}
|
|
6884
|
+
/**
|
|
6885
|
+
* Create a context in a group through the relay, as the author.
|
|
6886
|
+
*
|
|
6887
|
+
* Always asks {@link describeCreation} first — with the author, so both
|
|
6888
|
+
* standing checks happen before anything is signed. A relay without standing
|
|
6889
|
+
* in the group, or an author without `CAN_CREATE_CONTEXT`, is refused here as
|
|
6890
|
+
* an {@link IntentRefusedError} *before* a nonce is taken: the nonce source
|
|
6891
|
+
* is monotonic, and a warrant nobody will spend burns one for nothing.
|
|
6892
|
+
*
|
|
6893
|
+
* The creation warrant's nonce is spent in the new context's per-device
|
|
6894
|
+
* ledger — the same one later `execute` calls in that context draw from — so
|
|
6895
|
+
* it comes from the configured {@link NonceSource} like any other warrant.
|
|
6896
|
+
*
|
|
6897
|
+
* Sealing: nothing here is plaintext-specific. The request goes through the
|
|
6898
|
+
* injected `fetch`, so a `createAttestedSealedFetch` seals it exactly as it
|
|
6899
|
+
* seals `execute`. Whether the relay *accepts* it sealed is the node's call:
|
|
6900
|
+
* a proxy-auth relay only admits sealed requests for routes `merod` serves
|
|
6901
|
+
* without a credential, so `/admin-api/groups/:id/context-intents` must be on
|
|
6902
|
+
* that list on the core side or the request comes back
|
|
6903
|
+
* `403 sealed_route_unguarded`.
|
|
6904
|
+
*/
|
|
6905
|
+
async createContext(input) {
|
|
6906
|
+
const described = await this.describeCreation(input.groupId, {
|
|
6907
|
+
author: this.config.authorAccount
|
|
6908
|
+
});
|
|
6909
|
+
if (!described.canCreateOnBehalf) {
|
|
6910
|
+
throw new IntentRefusedError(
|
|
6911
|
+
`the relay (${described.executorAccount}) has no standing to act for members of group ${described.groupId}; an admin must admit it as a relay or grant it CAN_AUTHOR_ON_BEHALF (checked before signing \u2014 no nonce was spent)`,
|
|
6912
|
+
false,
|
|
6913
|
+
403
|
|
6914
|
+
);
|
|
6915
|
+
}
|
|
6916
|
+
if (described.authorMayCreate === false) {
|
|
6917
|
+
throw new IntentRefusedError(
|
|
6918
|
+
`the author (${this.config.authorAccount}) may not create contexts in group ${described.groupId}; it needs CAN_CREATE_CONTEXT or admin (checked before signing \u2014 no nonce was spent)`,
|
|
6919
|
+
false,
|
|
6920
|
+
403
|
|
6921
|
+
);
|
|
6922
|
+
}
|
|
6923
|
+
const configured = this.config.executorAccount;
|
|
6924
|
+
if (configured && configured.toLowerCase() !== described.executorAccount.toLowerCase()) {
|
|
6925
|
+
throw new Error(
|
|
6926
|
+
`configured executorAccount ${configured} is not the relay's account ${described.executorAccount}; a warrant naming it would be unspendable`
|
|
6927
|
+
);
|
|
6928
|
+
}
|
|
6929
|
+
const executor = described.executorAccount;
|
|
6930
|
+
this.executorAccount = executor;
|
|
6931
|
+
const initArgs = input.initArgs ?? {};
|
|
6932
|
+
const nonce2 = await this.config.nonces.next();
|
|
6933
|
+
const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
|
|
6934
|
+
const { warrant } = await signCreationWarrant({
|
|
6935
|
+
group: input.groupId,
|
|
6936
|
+
seed: input.seed,
|
|
6937
|
+
authorAccount: this.config.authorAccount,
|
|
6938
|
+
executor,
|
|
6939
|
+
applicationId: input.applicationId,
|
|
6940
|
+
serviceName: input.serviceName,
|
|
6941
|
+
name: input.name,
|
|
6942
|
+
initArgs,
|
|
6943
|
+
nonce: nonce2,
|
|
6944
|
+
notAfter: BigInt(Math.floor(Date.now() / 1e3)) + BigInt(ttl),
|
|
6945
|
+
deviceSecret: this.config.deviceSecret
|
|
6946
|
+
});
|
|
6947
|
+
const body = await this.json(
|
|
6948
|
+
"POST",
|
|
6949
|
+
`/admin-api/groups/${encodeURIComponent(input.groupId)}/context-intents`,
|
|
6950
|
+
{ warrant, authorProof: this.config.authorProof, initArgs }
|
|
6951
|
+
);
|
|
6952
|
+
return {
|
|
6953
|
+
contextId: body.data.contextId,
|
|
6954
|
+
groupId: body.data.groupId,
|
|
6955
|
+
memberPublicKey: body.data.memberPublicKey
|
|
6956
|
+
};
|
|
6957
|
+
}
|
|
6709
6958
|
async json(method, path, body) {
|
|
6710
6959
|
const headers = { Accept: "application/json" };
|
|
6711
6960
|
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
@@ -7405,8 +7654,8 @@ var REGISTERS = ["mrtd", "rtmr0", "rtmr1", "rtmr2", "rtmr3"];
|
|
|
7405
7654
|
function createQuoteVerifier(options) {
|
|
7406
7655
|
const allowedMrtd = measurements(options.allowedMrtd ?? [], "allowedMrtd");
|
|
7407
7656
|
const allowedImages = (options.allowedMeasurements ?? []).map((image, index) => {
|
|
7408
|
-
const
|
|
7409
|
-
return REGISTERS.map((register) => measurements([image?.[register] ?? ""], `${
|
|
7657
|
+
const label2 = `allowedMeasurements[${index}]`;
|
|
7658
|
+
return REGISTERS.map((register) => measurements([image?.[register] ?? ""], `${label2}.${register}`)[0]).join();
|
|
7410
7659
|
});
|
|
7411
7660
|
const allowedRtmr = [
|
|
7412
7661
|
measurements(options.allowedRtmr0 ?? [], "allowedRtmr0"),
|
|
@@ -7475,11 +7724,11 @@ function createQuoteVerifier(options) {
|
|
|
7475
7724
|
};
|
|
7476
7725
|
return Object.assign(verifier, { includeCollateral: true });
|
|
7477
7726
|
}
|
|
7478
|
-
function measurements(values,
|
|
7727
|
+
function measurements(values, label2) {
|
|
7479
7728
|
return values.map((value) => {
|
|
7480
7729
|
const normalized = value.trim().toLowerCase();
|
|
7481
7730
|
if (!MEASUREMENT_HEX.test(normalized)) {
|
|
7482
|
-
throw new Error(`${
|
|
7731
|
+
throw new Error(`${label2} holds ${JSON.stringify(value)}, which is not a 48-byte hex measurement`);
|
|
7483
7732
|
}
|
|
7484
7733
|
return normalized;
|
|
7485
7734
|
});
|
|
@@ -8101,18 +8350,18 @@ var ROOT_OP = {
|
|
|
8101
8350
|
NamespaceCreatedV2: 9,
|
|
8102
8351
|
MemberJoinedViaTeeAttestation: 10
|
|
8103
8352
|
};
|
|
8104
|
-
function bytes32(value,
|
|
8353
|
+
function bytes32(value, label2) {
|
|
8105
8354
|
if (value.length !== 32) {
|
|
8106
|
-
throw new Error(`${
|
|
8355
|
+
throw new Error(`${label2} must be 32 bytes, got ${value.length}`);
|
|
8107
8356
|
}
|
|
8108
8357
|
return new Uint8Array(value);
|
|
8109
8358
|
}
|
|
8110
|
-
function optionalBytes32(value,
|
|
8359
|
+
function optionalBytes32(value, label2) {
|
|
8111
8360
|
if (value === null || value === void 0) {
|
|
8112
8361
|
return new Uint8Array([0]);
|
|
8113
8362
|
}
|
|
8114
8363
|
if (value.length !== 32) {
|
|
8115
|
-
throw new Error(`${
|
|
8364
|
+
throw new Error(`${label2} must be 32 bytes, got ${value.length}`);
|
|
8116
8365
|
}
|
|
8117
8366
|
return concat(new Uint8Array([1]), new Uint8Array(value));
|
|
8118
8367
|
}
|
|
@@ -8194,7 +8443,7 @@ async function signMemberJoinOp(input) {
|
|
|
8194
8443
|
}
|
|
8195
8444
|
|
|
8196
8445
|
// src/login/login.ts
|
|
8197
|
-
var
|
|
8446
|
+
var SIGN_DOMAIN4 = new TextEncoder().encode("calimero.auth.login.v1");
|
|
8198
8447
|
var AUDIENCE_TAG = {
|
|
8199
8448
|
webOrigin: 0,
|
|
8200
8449
|
codeSigningId: 1,
|
|
@@ -8233,7 +8482,7 @@ async function signLoginStatement(input) {
|
|
|
8233
8482
|
const deviceKey = await derivePublicKey(input.deviceSecret);
|
|
8234
8483
|
const issuedAt = u64le(input.issuedAt);
|
|
8235
8484
|
const expiresAt = u64le(input.expiresAt);
|
|
8236
|
-
const preimage = await domainHash(
|
|
8485
|
+
const preimage = await domainHash(SIGN_DOMAIN4, [
|
|
8237
8486
|
node,
|
|
8238
8487
|
audienceSigningBytes(input.audience),
|
|
8239
8488
|
challenge,
|