@seams/wallet 0.5.1 → 0.5.2
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/LICENSE.md +201 -0
- package/THIRD_PARTY_NOTICES.md +15095 -0
- package/dist/.build-inputs.sha256 +1 -1
- package/dist/esm/SeamsWeb/signingSurface/BrowserSigningSurface.js +7 -14
- package/dist/esm/core/signingEngine/session/identity/exactWalletSessionReader.js +2 -27
- package/dist/esm/react/SeamsWeb/signingSurface/BrowserSigningSurface.js +7 -14
- package/dist/esm/react/core/signingEngine/session/identity/exactWalletSessionReader.js +2 -27
- package/dist/esm/sdk/export-private-key-viewer.js +8804 -55
- package/dist/esm/sdk/halo-border.js +8887 -8
- package/dist/esm/sdk/{host-BqwEYhX0.js → host-DNmO0eve.js} +2 -2
- package/dist/esm/sdk/passkey-halo-loading.js +8850 -27
- package/dist/{public/sdk/registrationPreparationPreload-u3ruCmpF.js → esm/sdk/registrationPreparationPreload-CwUkRwVz.js} +1 -1
- package/dist/esm/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/{public/sdk/runtime-auth-Da9yQyaD.js → esm/sdk/runtime-auth-dpoaCtkK.js} +2 -2
- package/dist/esm/sdk/{runtime-device-link-DNlzlwrr.js → runtime-device-link-C75epnbj.js} +1 -1
- package/dist/{public/sdk/runtime-ecdsa-tempo-B7dBVcCI.js → esm/sdk/runtime-ecdsa-tempo-CV-E-iZG.js} +1 -1
- package/dist/{public/sdk/runtime-email-otp-CckVQZJC.js → esm/sdk/runtime-email-otp-V0mdMD_t.js} +1 -1
- package/dist/{public/sdk/runtime-export-WAiBwZL_.js → esm/sdk/runtime-export-C4HO5ysH.js} +1 -1
- package/dist/esm/sdk/{runtime-near-DBJ4KfFv.js → runtime-near-DlviFQWy.js} +1 -1
- package/dist/{public/sdk/runtime-preferences-DmH7eMHH.js → esm/sdk/runtime-preferences-DyJidFuf.js} +1 -1
- package/dist/esm/sdk/{runtime-recovery-kPgl9nTT.js → runtime-recovery-CHDE5gl0.js} +1 -1
- package/dist/esm/sdk/{runtimeContext-BorCgXo5.js → runtimeContext-D_TkUM6Z.js} +6 -38
- package/dist/esm/sdk/{runtimeLoader-BKQjNgXO.js → runtimeLoader-DxiLgXPm.js} +9 -9
- package/dist/esm/sdk/tx-confirm-ui.js +9568 -206
- package/dist/esm/sdk/w3a-tx-confirmer.js +8335 -206
- package/dist/esm/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/esm/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker.js +4 -4
- package/dist/esm/wasm/near_signer/pkg/wasm_signer_worker_bg.wasm +0 -0
- package/dist/esm/wasm/router_ab_ecdsa_client/pkg/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/esm/wasm/router_ab_ed25519_yao_client/pkg/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/public/headers.manifest.json +1 -1
- package/dist/public/sdk/export-private-key-viewer.js +8804 -55
- package/dist/public/sdk/halo-border.js +8887 -8
- package/dist/public/sdk/{host-BqwEYhX0.js → host-DNmO0eve.js} +2 -2
- package/dist/public/sdk/passkey-halo-loading.js +8850 -27
- package/dist/{esm/sdk/registrationPreparationPreload-u3ruCmpF.js → public/sdk/registrationPreparationPreload-CwUkRwVz.js} +1 -1
- package/dist/public/sdk/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/{esm/sdk/runtime-auth-Da9yQyaD.js → public/sdk/runtime-auth-dpoaCtkK.js} +2 -2
- package/dist/public/sdk/{runtime-device-link-DNlzlwrr.js → runtime-device-link-C75epnbj.js} +1 -1
- package/dist/{esm/sdk/runtime-ecdsa-tempo-B7dBVcCI.js → public/sdk/runtime-ecdsa-tempo-CV-E-iZG.js} +1 -1
- package/dist/{esm/sdk/runtime-email-otp-CckVQZJC.js → public/sdk/runtime-email-otp-V0mdMD_t.js} +1 -1
- package/dist/{esm/sdk/runtime-export-WAiBwZL_.js → public/sdk/runtime-export-C4HO5ysH.js} +1 -1
- package/dist/public/sdk/{runtime-near-DBJ4KfFv.js → runtime-near-DlviFQWy.js} +1 -1
- package/dist/{esm/sdk/runtime-preferences-DmH7eMHH.js → public/sdk/runtime-preferences-DyJidFuf.js} +1 -1
- package/dist/public/sdk/{runtime-recovery-kPgl9nTT.js → runtime-recovery-CHDE5gl0.js} +1 -1
- package/dist/public/sdk/{runtimeContext-BorCgXo5.js → runtimeContext-D_TkUM6Z.js} +6 -38
- package/dist/public/sdk/{runtimeLoader-BKQjNgXO.js → runtimeLoader-DxiLgXPm.js} +9 -9
- package/dist/public/sdk/tx-confirm-ui.js +9568 -206
- package/dist/public/sdk/w3a-tx-confirmer.js +8335 -206
- package/dist/public/sdk/wallet-iframe-host-ecdsa.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-full.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-near.js +1 -1
- package/dist/public/sdk/wallet-iframe-host-runtime.js +1 -1
- package/dist/public/sdk/workers/device-linking-key.worker.js +8603 -3
- package/dist/public/sdk/workers/ecdsa-derivation-client.worker.js +12320 -1
- package/dist/public/sdk/workers/ecdsa-online-client.worker.js +623 -1
- package/dist/public/sdk/workers/ecdsa-presign-client.worker.js +1276 -1
- package/dist/public/sdk/workers/email-otp.worker.js +15653 -7
- package/dist/public/sdk/workers/email_otp_runtime.js +39 -3
- package/dist/public/sdk/workers/email_otp_runtime_bg.wasm +0 -0
- package/dist/public/sdk/workers/evm-crypto.worker.js +1157 -5
- package/dist/public/sdk/workers/evm_crypto.wasm +0 -0
- package/dist/public/sdk/workers/evm_crypto_bg.wasm +0 -0
- package/dist/public/sdk/workers/near-signer.worker.js +1631 -2
- package/dist/public/sdk/workers/near_signer.wasm +0 -0
- package/dist/public/sdk/workers/passkey-confirm.worker.js +606 -1
- package/dist/public/sdk/workers/passkey-mpc-export.worker.js +5406 -2
- package/dist/public/sdk/workers/passkey-mpc-session.worker.js +1717 -1
- package/dist/public/sdk/workers/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/public/sdk/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/public/sdk/workers/shamir3pass.worker.js +874 -4
- package/dist/public/sdk/workers/shamir3pass_runtime.js +84 -31
- package/dist/public/sdk/workers/shamir3pass_runtime_bg.wasm +0 -0
- package/dist/public/sdk/workers/tempo-signer.worker.js +987 -5
- package/dist/public/sdk/workers/tempo_signer.wasm +0 -0
- package/dist/public/sdk/workers/tempo_signer_bg.wasm +0 -0
- package/dist/public/sdk/workers/wallet-custody-ceremony.worker.js +55 -1244
- package/dist/public/sdk/workers/wallet_custody_ceremony_bg.wasm +0 -0
- package/dist/public/sdk/workers/wasm_signer_worker_bg.wasm +0 -0
- package/dist/public/wallet-assets.manifest.json +32 -32
- package/dist/types/wallet/src/SeamsWeb/signingSurface/BrowserSigningSurface.d.ts +4 -4
- package/dist/types/wallet/src/core/signingEngine/session/identity/exactWalletSessionReader.d.ts +1 -9
- package/dist/workers/device-linking-key.worker.js +8603 -3
- package/dist/workers/ecdsa-derivation-client.worker.js +12320 -1
- package/dist/workers/ecdsa-online-client.worker.js +623 -1
- package/dist/workers/ecdsa-presign-client.worker.js +1276 -1
- package/dist/workers/email-otp.worker.js +15653 -7
- package/dist/workers/email_otp_runtime.js +39 -3
- package/dist/workers/email_otp_runtime_bg.wasm +0 -0
- package/dist/workers/evm-crypto.worker.js +1157 -5
- package/dist/workers/evm_crypto.wasm +0 -0
- package/dist/workers/evm_crypto_bg.wasm +0 -0
- package/dist/workers/near-signer.worker.js +1631 -2
- package/dist/workers/near_signer.wasm +0 -0
- package/dist/workers/passkey-confirm.worker.js +606 -1
- package/dist/workers/passkey-mpc-export.worker.js +5406 -2
- package/dist/workers/passkey-mpc-session.worker.js +1717 -1
- package/dist/workers/router_ab_ecdsa_client_bg.wasm +0 -0
- package/dist/workers/router_ab_ed25519_yao_client_bg.wasm +0 -0
- package/dist/workers/shamir3pass.worker.js +874 -4
- package/dist/workers/shamir3pass_runtime.js +84 -31
- package/dist/workers/shamir3pass_runtime_bg.wasm +0 -0
- package/dist/workers/tempo-signer.worker.js +987 -5
- package/dist/workers/tempo_signer.wasm +0 -0
- package/dist/workers/tempo_signer_bg.wasm +0 -0
- package/dist/workers/wallet-custody-ceremony.worker.js +55 -1244
- package/dist/workers/wallet_custody_ceremony_bg.wasm +0 -0
- package/dist/workers/wasm_signer_worker_bg.wasm +0 -0
- package/package.json +5 -2
- package/LICENSE +0 -21
|
Binary file
|
|
@@ -1 +1,606 @@
|
|
|
1
|
-
|
|
1
|
+
// ../shared-ts/src/utils/normalize.ts
|
|
2
|
+
function normalizeTrimmedString(value) {
|
|
3
|
+
return String(value ?? "").trim();
|
|
4
|
+
}
|
|
5
|
+
function normalizeOptionalNonEmptyString(value) {
|
|
6
|
+
const normalized = normalizeTrimmedString(value);
|
|
7
|
+
return normalized || undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// ../../node_modules/base-x/src/esm/index.js
|
|
11
|
+
function base(ALPHABET) {
|
|
12
|
+
if (ALPHABET.length >= 255) {
|
|
13
|
+
throw new TypeError("Alphabet too long");
|
|
14
|
+
}
|
|
15
|
+
const BASE_MAP = new Uint8Array(256);
|
|
16
|
+
for (let j = 0;j < BASE_MAP.length; j++) {
|
|
17
|
+
BASE_MAP[j] = 255;
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0;i < ALPHABET.length; i++) {
|
|
20
|
+
const x = ALPHABET.charAt(i);
|
|
21
|
+
const xc = x.charCodeAt(0);
|
|
22
|
+
if (BASE_MAP[xc] !== 255) {
|
|
23
|
+
throw new TypeError(x + " is ambiguous");
|
|
24
|
+
}
|
|
25
|
+
BASE_MAP[xc] = i;
|
|
26
|
+
}
|
|
27
|
+
const BASE = ALPHABET.length;
|
|
28
|
+
const LEADER = ALPHABET.charAt(0);
|
|
29
|
+
const FACTOR = Math.log(BASE) / Math.log(256);
|
|
30
|
+
const iFACTOR = Math.log(256) / Math.log(BASE);
|
|
31
|
+
function encode(source) {
|
|
32
|
+
if (source instanceof Uint8Array) {} else if (ArrayBuffer.isView(source)) {
|
|
33
|
+
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
|
|
34
|
+
} else if (Array.isArray(source)) {
|
|
35
|
+
source = Uint8Array.from(source);
|
|
36
|
+
}
|
|
37
|
+
if (!(source instanceof Uint8Array)) {
|
|
38
|
+
throw new TypeError("Expected Uint8Array");
|
|
39
|
+
}
|
|
40
|
+
if (source.length === 0) {
|
|
41
|
+
return "";
|
|
42
|
+
}
|
|
43
|
+
let zeroes = 0;
|
|
44
|
+
let length = 0;
|
|
45
|
+
let pbegin = 0;
|
|
46
|
+
const pend = source.length;
|
|
47
|
+
while (pbegin !== pend && source[pbegin] === 0) {
|
|
48
|
+
pbegin++;
|
|
49
|
+
zeroes++;
|
|
50
|
+
}
|
|
51
|
+
const size = (pend - pbegin) * iFACTOR + 1 >>> 0;
|
|
52
|
+
const b58 = new Uint8Array(size);
|
|
53
|
+
while (pbegin !== pend) {
|
|
54
|
+
let carry = source[pbegin];
|
|
55
|
+
let i = 0;
|
|
56
|
+
for (let it1 = size - 1;(carry !== 0 || i < length) && it1 !== -1; it1--, i++) {
|
|
57
|
+
carry += 256 * b58[it1] >>> 0;
|
|
58
|
+
b58[it1] = carry % BASE >>> 0;
|
|
59
|
+
carry = carry / BASE >>> 0;
|
|
60
|
+
}
|
|
61
|
+
if (carry !== 0) {
|
|
62
|
+
throw new Error("Non-zero carry");
|
|
63
|
+
}
|
|
64
|
+
length = i;
|
|
65
|
+
pbegin++;
|
|
66
|
+
}
|
|
67
|
+
let it2 = size - length;
|
|
68
|
+
while (it2 !== size && b58[it2] === 0) {
|
|
69
|
+
it2++;
|
|
70
|
+
}
|
|
71
|
+
let str = LEADER.repeat(zeroes);
|
|
72
|
+
for (;it2 < size; ++it2) {
|
|
73
|
+
str += ALPHABET.charAt(b58[it2]);
|
|
74
|
+
}
|
|
75
|
+
return str;
|
|
76
|
+
}
|
|
77
|
+
function decodeUnsafe(source) {
|
|
78
|
+
if (typeof source !== "string") {
|
|
79
|
+
throw new TypeError("Expected String");
|
|
80
|
+
}
|
|
81
|
+
if (source.length === 0) {
|
|
82
|
+
return new Uint8Array;
|
|
83
|
+
}
|
|
84
|
+
let psz = 0;
|
|
85
|
+
let zeroes = 0;
|
|
86
|
+
let length = 0;
|
|
87
|
+
while (source[psz] === LEADER) {
|
|
88
|
+
zeroes++;
|
|
89
|
+
psz++;
|
|
90
|
+
}
|
|
91
|
+
const size = (source.length - psz) * FACTOR + 1 >>> 0;
|
|
92
|
+
const b256 = new Uint8Array(size);
|
|
93
|
+
while (psz < source.length) {
|
|
94
|
+
const charCode = source.charCodeAt(psz);
|
|
95
|
+
if (charCode > 255) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
let carry = BASE_MAP[charCode];
|
|
99
|
+
if (carry === 255) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
let i = 0;
|
|
103
|
+
for (let it3 = size - 1;(carry !== 0 || i < length) && it3 !== -1; it3--, i++) {
|
|
104
|
+
carry += BASE * b256[it3] >>> 0;
|
|
105
|
+
b256[it3] = carry % 256 >>> 0;
|
|
106
|
+
carry = carry / 256 >>> 0;
|
|
107
|
+
}
|
|
108
|
+
if (carry !== 0) {
|
|
109
|
+
throw new Error("Non-zero carry");
|
|
110
|
+
}
|
|
111
|
+
length = i;
|
|
112
|
+
psz++;
|
|
113
|
+
}
|
|
114
|
+
let it4 = size - length;
|
|
115
|
+
while (it4 !== size && b256[it4] === 0) {
|
|
116
|
+
it4++;
|
|
117
|
+
}
|
|
118
|
+
const vch = new Uint8Array(zeroes + (size - it4));
|
|
119
|
+
let j = zeroes;
|
|
120
|
+
while (it4 !== size) {
|
|
121
|
+
vch[j++] = b256[it4++];
|
|
122
|
+
}
|
|
123
|
+
return vch;
|
|
124
|
+
}
|
|
125
|
+
function decode(string) {
|
|
126
|
+
const buffer = decodeUnsafe(string);
|
|
127
|
+
if (buffer) {
|
|
128
|
+
return buffer;
|
|
129
|
+
}
|
|
130
|
+
throw new Error("Non-base" + BASE + " character");
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
encode,
|
|
134
|
+
decodeUnsafe,
|
|
135
|
+
decode
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
var esm_default = base;
|
|
139
|
+
|
|
140
|
+
// ../../node_modules/bs58/src/esm/index.js
|
|
141
|
+
var ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
142
|
+
var esm_default2 = esm_default(ALPHABET);
|
|
143
|
+
// ../shared-ts/src/utils/validation.ts
|
|
144
|
+
function isObject(x) {
|
|
145
|
+
return x !== null && typeof x === "object";
|
|
146
|
+
}
|
|
147
|
+
function isString(x) {
|
|
148
|
+
return typeof x === "string";
|
|
149
|
+
}
|
|
150
|
+
function isBoolean(x) {
|
|
151
|
+
return typeof x === "boolean";
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// ../shared-ts/src/utils/errors.ts
|
|
155
|
+
function errorMessage(err) {
|
|
156
|
+
try {
|
|
157
|
+
if (typeof err === "string")
|
|
158
|
+
return err;
|
|
159
|
+
if (err && typeof err.message === "string") {
|
|
160
|
+
return err.message;
|
|
161
|
+
}
|
|
162
|
+
return String(err ?? "");
|
|
163
|
+
} catch {
|
|
164
|
+
return "";
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function b64uField(prefix) {
|
|
168
|
+
return `${prefix}B64u`;
|
|
169
|
+
}
|
|
170
|
+
var SENSITIVE_ERROR_FIELD_NAMES = [
|
|
171
|
+
"nearPrivateKey",
|
|
172
|
+
"near_private_key",
|
|
173
|
+
"privateKey",
|
|
174
|
+
"private_key",
|
|
175
|
+
b64uField("seed"),
|
|
176
|
+
"seed_b64u",
|
|
177
|
+
b64uField("canonicalSeed"),
|
|
178
|
+
"canonical_seed_b64u",
|
|
179
|
+
b64uField("xClientBase"),
|
|
180
|
+
"x_client_base_b64u",
|
|
181
|
+
b64uField("clientOutputMask"),
|
|
182
|
+
"client_output_mask_b64u",
|
|
183
|
+
b64uField("clientRecoverableSecret"),
|
|
184
|
+
"client_recoverable_secret_b64u",
|
|
185
|
+
"prfOutput",
|
|
186
|
+
"prf_output",
|
|
187
|
+
"prfFirst",
|
|
188
|
+
"prf_first",
|
|
189
|
+
b64uField("prfFirst"),
|
|
190
|
+
"prf_first_b64u",
|
|
191
|
+
"prfSecond",
|
|
192
|
+
"prf_second",
|
|
193
|
+
b64uField("prfSecond"),
|
|
194
|
+
"prf_second_b64u",
|
|
195
|
+
b64uField("signingShare32"),
|
|
196
|
+
"signing_share32_b64u",
|
|
197
|
+
b64uField("clientNonceHandle"),
|
|
198
|
+
"client_nonce_handle_b64u"
|
|
199
|
+
];
|
|
200
|
+
function toError(e) {
|
|
201
|
+
if (e instanceof Error)
|
|
202
|
+
return e;
|
|
203
|
+
const err = new Error(errorMessage(e));
|
|
204
|
+
try {
|
|
205
|
+
const src = e;
|
|
206
|
+
if (typeof src?.name === "string")
|
|
207
|
+
err.name = src.name;
|
|
208
|
+
if (typeof src?.stack === "string")
|
|
209
|
+
err.stack = src.stack;
|
|
210
|
+
if (src && typeof src.code !== "undefined")
|
|
211
|
+
err.code = src.code;
|
|
212
|
+
if (src && typeof src.details !== "undefined")
|
|
213
|
+
err.details = src.details;
|
|
214
|
+
} catch {}
|
|
215
|
+
return err;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ../shared-ts/src/utils/base64.ts
|
|
219
|
+
var base64Encode = (value) => {
|
|
220
|
+
const bytes = ArrayBuffer.isView(value) ? new Uint8Array(value.buffer, value.byteOffset, value.byteLength) : new Uint8Array(value);
|
|
221
|
+
let binary = "";
|
|
222
|
+
for (let i = 0;i < bytes.length; i++) {
|
|
223
|
+
binary += String.fromCharCode(bytes[i]);
|
|
224
|
+
}
|
|
225
|
+
return btoa(binary);
|
|
226
|
+
};
|
|
227
|
+
var base64UrlEncode = (value) => {
|
|
228
|
+
return base64Encode(value).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// ../shared-ts/src/utils/secureRandomId.ts
|
|
232
|
+
var DEFAULT_SECURE_RANDOM_ID_BYTES = 32;
|
|
233
|
+
function secureRandomBytes(length = DEFAULT_SECURE_RANDOM_ID_BYTES, label = "secure random bytes") {
|
|
234
|
+
const byteLength = Math.max(1, Math.floor(Number(length) || 0));
|
|
235
|
+
const cryptoApi = globalThis.crypto;
|
|
236
|
+
if (typeof cryptoApi?.getRandomValues !== "function") {
|
|
237
|
+
throw new Error(`WebCrypto getRandomValues is required for ${label}`);
|
|
238
|
+
}
|
|
239
|
+
return cryptoApi.getRandomValues(new Uint8Array(byteLength));
|
|
240
|
+
}
|
|
241
|
+
function secureRandomBase64Url(byteLength = DEFAULT_SECURE_RANDOM_ID_BYTES, label = "secure random id") {
|
|
242
|
+
return base64UrlEncode(secureRandomBytes(byteLength, label));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// src/core/signingEngine/uiConfirm/awaitUserConfirmation.ts
|
|
246
|
+
function awaitUserConfirmationV2(promptInput, opts = {}) {
|
|
247
|
+
let prompt;
|
|
248
|
+
let requestId;
|
|
249
|
+
try {
|
|
250
|
+
prompt = normalizeConfirmPrompt(promptInput);
|
|
251
|
+
requestId = requestIdForPrompt(prompt);
|
|
252
|
+
} catch (error) {
|
|
253
|
+
return Promise.reject(new Error(`[signer-worker]: invalid confirmation prompt: ${toError(error).message}`));
|
|
254
|
+
}
|
|
255
|
+
return new Promise((resolve, reject) => {
|
|
256
|
+
const channelToken = createChannelToken(requestId);
|
|
257
|
+
let timeoutId;
|
|
258
|
+
const cleanup = () => {
|
|
259
|
+
if (timeoutId)
|
|
260
|
+
clearTimeout(timeoutId);
|
|
261
|
+
self.removeEventListener("message", onDecisionReceived);
|
|
262
|
+
if (opts.signal)
|
|
263
|
+
opts.signal.removeEventListener("abort", onAbort);
|
|
264
|
+
};
|
|
265
|
+
const onAbort = () => {
|
|
266
|
+
cleanup();
|
|
267
|
+
reject(new Error("[signer-worker]: confirmation aborted"));
|
|
268
|
+
};
|
|
269
|
+
const onDecisionReceived = (messageEvent) => {
|
|
270
|
+
const env = messageEvent?.data;
|
|
271
|
+
if (!isConfirmResponseEnvelope(env))
|
|
272
|
+
return;
|
|
273
|
+
if (!isValidUserConfirmOrigin(messageEvent))
|
|
274
|
+
return;
|
|
275
|
+
if (resolveEnvelopeRequestId(env) !== requestId)
|
|
276
|
+
return;
|
|
277
|
+
if (!isMatchingChannelToken(env, channelToken))
|
|
278
|
+
return;
|
|
279
|
+
cleanup();
|
|
280
|
+
let response;
|
|
281
|
+
try {
|
|
282
|
+
response = env.data.confirmed ? buildConfirmedWorkerConfirmationResponse({
|
|
283
|
+
requestId,
|
|
284
|
+
data: env.data
|
|
285
|
+
}) : env.data.walletSessionFailure ? {
|
|
286
|
+
request_id: requestId,
|
|
287
|
+
intent_digest: env.data.intentDigest,
|
|
288
|
+
confirmed: false,
|
|
289
|
+
registration_diagnostics: env.data.registrationDiagnostics,
|
|
290
|
+
wallet_session_failure: env.data.walletSessionFailure
|
|
291
|
+
} : {
|
|
292
|
+
request_id: requestId,
|
|
293
|
+
intent_digest: env.data.intentDigest,
|
|
294
|
+
confirmed: false,
|
|
295
|
+
registration_diagnostics: env.data.registrationDiagnostics,
|
|
296
|
+
error: env.data.error
|
|
297
|
+
};
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return reject(toError(error));
|
|
300
|
+
}
|
|
301
|
+
return resolve(response);
|
|
302
|
+
};
|
|
303
|
+
self.addEventListener("message", onDecisionReceived);
|
|
304
|
+
if (opts.timeoutMs && opts.timeoutMs > 0) {
|
|
305
|
+
timeoutId = setTimeout(() => {
|
|
306
|
+
cleanup();
|
|
307
|
+
reject(new Error("[signer-worker]: confirmation timed out"));
|
|
308
|
+
}, opts.timeoutMs);
|
|
309
|
+
}
|
|
310
|
+
if (opts.signal) {
|
|
311
|
+
if (opts.signal.aborted) {
|
|
312
|
+
cleanup();
|
|
313
|
+
return reject(new Error("[signer-worker]: confirmation aborted"));
|
|
314
|
+
}
|
|
315
|
+
opts.signal.addEventListener("abort", onAbort);
|
|
316
|
+
}
|
|
317
|
+
try {
|
|
318
|
+
const promptEnvelope = {
|
|
319
|
+
type: "PROMPT_USER_CONFIRM_IN_JS_MAIN_THREAD" /* PROMPT_USER_CONFIRM_IN_JS_MAIN_THREAD */,
|
|
320
|
+
requestId,
|
|
321
|
+
channelToken,
|
|
322
|
+
data: prompt
|
|
323
|
+
};
|
|
324
|
+
self.postMessage(promptEnvelope);
|
|
325
|
+
} catch (postErr) {
|
|
326
|
+
cleanup();
|
|
327
|
+
console.error("[signer-worker][V2] postMessage failed", postErr);
|
|
328
|
+
return reject(toError(postErr));
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
function normalizeConfirmPrompt(input) {
|
|
333
|
+
if (!isObject(input)) {
|
|
334
|
+
throw new Error("expected an object");
|
|
335
|
+
}
|
|
336
|
+
if (input.kind === "pending_request") {
|
|
337
|
+
const requestId = normalizePromptRequestId(input.requestId);
|
|
338
|
+
const requestToken = normalizePromptRequestToken(input.requestToken);
|
|
339
|
+
return { kind: "pending_request", requestId, requestToken };
|
|
340
|
+
}
|
|
341
|
+
if (input.kind === "export_request") {
|
|
342
|
+
if (!isObject(input.request)) {
|
|
343
|
+
throw new Error("export request is missing");
|
|
344
|
+
}
|
|
345
|
+
normalizePromptRequestId(input.request.requestId);
|
|
346
|
+
return input;
|
|
347
|
+
}
|
|
348
|
+
throw new Error("unsupported prompt kind");
|
|
349
|
+
}
|
|
350
|
+
function requestIdForPrompt(prompt) {
|
|
351
|
+
switch (prompt.kind) {
|
|
352
|
+
case "pending_request":
|
|
353
|
+
return prompt.requestId;
|
|
354
|
+
case "export_request":
|
|
355
|
+
return normalizePromptRequestId(prompt.request.requestId);
|
|
356
|
+
default:
|
|
357
|
+
return assertNever(prompt);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
function normalizePromptRequestId(value) {
|
|
361
|
+
if (!isString(value)) {
|
|
362
|
+
throw new Error("missing requestId");
|
|
363
|
+
}
|
|
364
|
+
const requestId = value.trim();
|
|
365
|
+
if (!requestId) {
|
|
366
|
+
throw new Error("missing requestId");
|
|
367
|
+
}
|
|
368
|
+
return requestId;
|
|
369
|
+
}
|
|
370
|
+
function normalizePromptRequestToken(value) {
|
|
371
|
+
if (!isString(value)) {
|
|
372
|
+
throw new Error("missing requestToken");
|
|
373
|
+
}
|
|
374
|
+
const requestToken = value.trim();
|
|
375
|
+
if (!requestToken) {
|
|
376
|
+
throw new Error("missing requestToken");
|
|
377
|
+
}
|
|
378
|
+
return requestToken;
|
|
379
|
+
}
|
|
380
|
+
function assertNever(value) {
|
|
381
|
+
throw new Error(`Unexpected confirmation prompt kind: ${String(value)}`);
|
|
382
|
+
}
|
|
383
|
+
function buildConfirmedWorkerConfirmationResponse(args) {
|
|
384
|
+
const nonceLeases = normalizeNonceLeaseRefs(args.data.nonceLeases);
|
|
385
|
+
const base = {
|
|
386
|
+
request_id: args.requestId,
|
|
387
|
+
confirmed: true,
|
|
388
|
+
...args.data.intentDigest ? { intent_digest: args.data.intentDigest } : {},
|
|
389
|
+
...args.data.credential ? { credential: args.data.credential } : {},
|
|
390
|
+
...args.data.operationStepUpPreparation ? { operation_step_up_preparation: args.data.operationStepUpPreparation } : {},
|
|
391
|
+
...args.data.otpCode ? { otp_code: args.data.otpCode } : {},
|
|
392
|
+
...args.data.emailOtpChallengeId ? { email_otp_challenge_id: args.data.emailOtpChallengeId } : {},
|
|
393
|
+
...args.data.registrationDiagnostics ? { registration_diagnostics: args.data.registrationDiagnostics } : {}
|
|
394
|
+
};
|
|
395
|
+
if (args.data.nearTransactionReadiness) {
|
|
396
|
+
if (args.data.transactionContext || nonceLeases !== undefined) {
|
|
397
|
+
throw new Error("Secure confirm NEAR readiness cannot include top-level transaction context");
|
|
398
|
+
}
|
|
399
|
+
return {
|
|
400
|
+
...base,
|
|
401
|
+
near_transaction_readiness: args.data.nearTransactionReadiness
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
if (args.data.transactionContext) {
|
|
405
|
+
if (!nonceLeases?.length) {
|
|
406
|
+
throw new Error("Secure confirm transaction response requires nonceLeases");
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
...base,
|
|
410
|
+
transaction_context: args.data.transactionContext,
|
|
411
|
+
nonce_leases: nonceLeases
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
if (nonceLeases !== undefined) {
|
|
415
|
+
throw new Error("Secure confirm response nonceLeases require transactionContext");
|
|
416
|
+
}
|
|
417
|
+
return base;
|
|
418
|
+
}
|
|
419
|
+
function normalizeNonceLeaseRefs(value) {
|
|
420
|
+
if (value == null)
|
|
421
|
+
return;
|
|
422
|
+
if (!Array.isArray(value)) {
|
|
423
|
+
throw new Error("Invalid secure confirm response nonceLeases: expected array");
|
|
424
|
+
}
|
|
425
|
+
return value.map(normalizeNonceLeaseRef);
|
|
426
|
+
}
|
|
427
|
+
function normalizeNonceLeaseRef(value) {
|
|
428
|
+
if (!isObject(value)) {
|
|
429
|
+
throw new Error("Invalid secure confirm response nonceLease: expected object");
|
|
430
|
+
}
|
|
431
|
+
const leaseId = normalizeNonceLeaseString(value.leaseId, "nonceLease.leaseId");
|
|
432
|
+
const operationId = normalizeNonceLeaseString(value.operationId, "nonceLease.operationId");
|
|
433
|
+
const operationFingerprint = normalizeNonceLeaseString(value.operationFingerprint, "nonceLease.operationFingerprint");
|
|
434
|
+
const nonce = normalizeNonceLeaseString(value.nonce, "nonceLease.nonce");
|
|
435
|
+
const batchId = value.batchId == null ? undefined : normalizeNonceLeaseString(value.batchId, "nonceLease.batchId");
|
|
436
|
+
const txIndex = normalizeNonceLeaseTxIndex(value.txIndex);
|
|
437
|
+
return {
|
|
438
|
+
leaseId,
|
|
439
|
+
operationId,
|
|
440
|
+
operationFingerprint,
|
|
441
|
+
nonce,
|
|
442
|
+
...batchId ? { batchId } : {},
|
|
443
|
+
...txIndex !== undefined ? { txIndex } : {}
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
function normalizeNonceLeaseString(value, field) {
|
|
447
|
+
if (!isString(value)) {
|
|
448
|
+
throw new Error(`Invalid secure confirm response ${field}: expected string`);
|
|
449
|
+
}
|
|
450
|
+
const normalized = value.trim();
|
|
451
|
+
if (!normalized) {
|
|
452
|
+
throw new Error(`Invalid secure confirm response ${field}: expected non-empty string`);
|
|
453
|
+
}
|
|
454
|
+
return normalized;
|
|
455
|
+
}
|
|
456
|
+
function normalizeNonceLeaseTxIndex(value) {
|
|
457
|
+
if (value == null)
|
|
458
|
+
return;
|
|
459
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value)) {
|
|
460
|
+
throw new Error("Invalid secure confirm response nonceLease.txIndex: expected safe integer");
|
|
461
|
+
}
|
|
462
|
+
return value;
|
|
463
|
+
}
|
|
464
|
+
function isConfirmResponseEnvelope(msg) {
|
|
465
|
+
if (!isObject(msg))
|
|
466
|
+
return false;
|
|
467
|
+
if (msg.type !== "USER_PASSKEY_CONFIRM_RESPONSE" /* USER_PASSKEY_CONFIRM_RESPONSE */)
|
|
468
|
+
return false;
|
|
469
|
+
const data = msg.data;
|
|
470
|
+
if (!isObject(data))
|
|
471
|
+
return false;
|
|
472
|
+
return isString(data.requestId) && isBoolean(data.confirmed);
|
|
473
|
+
}
|
|
474
|
+
function createChannelToken(requestId) {
|
|
475
|
+
const seed = String(requestId || "").trim() || "sc";
|
|
476
|
+
const randomPart = secureRandomBase64Url(32, "user confirmation channel tokens");
|
|
477
|
+
return `${seed}:${randomPart}`;
|
|
478
|
+
}
|
|
479
|
+
function resolveEnvelopeRequestId(env) {
|
|
480
|
+
const topLevelRequestId = isString(env.requestId) ? env.requestId.trim() : "";
|
|
481
|
+
if (topLevelRequestId) {
|
|
482
|
+
return topLevelRequestId;
|
|
483
|
+
}
|
|
484
|
+
return String(env.data.requestId || "").trim();
|
|
485
|
+
}
|
|
486
|
+
function isMatchingChannelToken(env, expectedChannelToken) {
|
|
487
|
+
return (normalizeOptionalNonEmptyString(env.channelToken) || "") === expectedChannelToken;
|
|
488
|
+
}
|
|
489
|
+
function isValidUserConfirmOrigin(messageEvent) {
|
|
490
|
+
const origin = messageEvent.origin.trim();
|
|
491
|
+
if (!origin) {
|
|
492
|
+
return true;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
const selfOrigin = String(self.location?.origin || "").trim();
|
|
496
|
+
return !!selfOrigin && origin === selfOrigin;
|
|
497
|
+
} catch {
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/core/signingEngine/workerManager/workers/passkey-confirm.worker.ts
|
|
503
|
+
globalThis.awaitUserConfirmationV2 = awaitUserConfirmationV2;
|
|
504
|
+
function asRecord(value) {
|
|
505
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
506
|
+
}
|
|
507
|
+
function asIncomingMessage(value) {
|
|
508
|
+
const record = asRecord(value);
|
|
509
|
+
return record ? {
|
|
510
|
+
id: record.id,
|
|
511
|
+
type: record.type,
|
|
512
|
+
payload: record.payload
|
|
513
|
+
} : {};
|
|
514
|
+
}
|
|
515
|
+
function postUserConfirmWorkerResponse(id, payload) {
|
|
516
|
+
const response = payload.success === true ? {
|
|
517
|
+
...typeof id === "string" && id.trim() ? { id: id.trim() } : {},
|
|
518
|
+
success: true,
|
|
519
|
+
data: payload.data
|
|
520
|
+
} : {
|
|
521
|
+
...typeof id === "string" && id.trim() ? { id: id.trim() } : {},
|
|
522
|
+
success: false,
|
|
523
|
+
error: payload.error
|
|
524
|
+
};
|
|
525
|
+
self.postMessage(response);
|
|
526
|
+
}
|
|
527
|
+
function forwardUserConfirmProgressToHost(value) {
|
|
528
|
+
const envelope = asRecord(value);
|
|
529
|
+
if (envelope)
|
|
530
|
+
self.postMessage(envelope);
|
|
531
|
+
}
|
|
532
|
+
function parseSecureConfirmRequestPayload(value) {
|
|
533
|
+
const record = asRecord(value);
|
|
534
|
+
if (!record)
|
|
535
|
+
return null;
|
|
536
|
+
if ("request" in record)
|
|
537
|
+
return null;
|
|
538
|
+
const requestId = typeof record.requestId === "string" ? record.requestId.trim() : "";
|
|
539
|
+
return requestId ? { requestId } : null;
|
|
540
|
+
}
|
|
541
|
+
self.onmessage = (event) => {
|
|
542
|
+
const incoming = asIncomingMessage(event.data);
|
|
543
|
+
const eventType = incoming.type;
|
|
544
|
+
if (eventType === "USER_PASSKEY_CONFIRM_RESPONSE" /* USER_PASSKEY_CONFIRM_RESPONSE */)
|
|
545
|
+
return;
|
|
546
|
+
if (eventType === "USER_PASSKEY_CONFIRM_PROGRESS" /* USER_PASSKEY_CONFIRM_PROGRESS */) {
|
|
547
|
+
forwardUserConfirmProgressToHost(event.data);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const id = incoming.id;
|
|
551
|
+
if (eventType === "PING") {
|
|
552
|
+
postUserConfirmWorkerResponse(id, { success: true, data: { ok: true } });
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
if (eventType === "SECURE_CONFIRM_REQUEST") {
|
|
556
|
+
(async () => {
|
|
557
|
+
try {
|
|
558
|
+
const payload = asRecord(incoming.payload);
|
|
559
|
+
const request = parseSecureConfirmRequestPayload(payload);
|
|
560
|
+
if (!request) {
|
|
561
|
+
postUserConfirmWorkerResponse(id, {
|
|
562
|
+
success: false,
|
|
563
|
+
error: "Invalid SECURE_CONFIRM_REQUEST payload: missing requestId"
|
|
564
|
+
});
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const requestToken = typeof id === "string" ? id.trim() : "";
|
|
568
|
+
if (!requestToken) {
|
|
569
|
+
postUserConfirmWorkerResponse(id, {
|
|
570
|
+
success: false,
|
|
571
|
+
error: "Invalid SECURE_CONFIRM_REQUEST message: missing id"
|
|
572
|
+
});
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
await awaitUserConfirmationV2({
|
|
576
|
+
kind: "pending_request",
|
|
577
|
+
requestId: request.requestId,
|
|
578
|
+
requestToken
|
|
579
|
+
});
|
|
580
|
+
postUserConfirmWorkerResponse(id, {
|
|
581
|
+
success: true,
|
|
582
|
+
data: { ok: true }
|
|
583
|
+
});
|
|
584
|
+
} catch (error) {
|
|
585
|
+
postUserConfirmWorkerResponse(id, {
|
|
586
|
+
success: false,
|
|
587
|
+
error: error instanceof Error ? error.message : String(error)
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
})();
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
if (typeof id === "string" && id.trim()) {
|
|
594
|
+
postUserConfirmWorkerResponse(id, {
|
|
595
|
+
success: false,
|
|
596
|
+
error: `Unsupported UserConfirm worker message type: ${String(eventType)}`
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
};
|
|
600
|
+
self.onerror = (error) => {
|
|
601
|
+
console.error("[passkey-confirm-worker] error:", error);
|
|
602
|
+
};
|
|
603
|
+
self.onunhandledrejection = (event) => {
|
|
604
|
+
console.error("[passkey-confirm-worker] Unhandled promise rejection:", event.reason);
|
|
605
|
+
event.preventDefault();
|
|
606
|
+
};
|