@anywalletkit/extension-kit 0.3.1 → 0.3.4
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/index.cjs +33 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +14 -3
- package/dist/index.d.ts +14 -3
- package/dist/index.js +33 -10
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
package/dist/index.cjs
CHANGED
|
@@ -223,6 +223,8 @@ var aadDekV1 = (kdf) => `forgewallet-vault/1/dek/${kdf.name}/${kdf.iterations}/$
|
|
|
223
223
|
var aadDekV2 = (kdf) => `forgewallet-vault/2/dek/scrypt/${kdf.N}/${kdf.r}/${kdf.p}/${kdf.salt}`;
|
|
224
224
|
var aadPasskey = (id) => `forgewallet-vault/2/passkey/${id}`;
|
|
225
225
|
var aadSecret = (id) => `forgewallet-vault/secret/${id}`;
|
|
226
|
+
var AAD_DEK_CHECK = "forgewallet-vault/dek-check";
|
|
227
|
+
var DEK_CHECK = "forgewallet-vault/dek-check/1";
|
|
226
228
|
var HKDF_INFO = "forgewallet-vault/2/passkey";
|
|
227
229
|
var Vault = class {
|
|
228
230
|
_storage;
|
|
@@ -436,7 +438,7 @@ var Vault = class {
|
|
|
436
438
|
const key = await this._importDek(dek);
|
|
437
439
|
return this._exclusive(async () => {
|
|
438
440
|
const envelope = await this._load();
|
|
439
|
-
if (Object.keys(envelope.secrets).length > 0) await this._requireDek(dek, envelope);
|
|
441
|
+
if (envelope.dekCheck !== void 0 || Object.keys(envelope.secrets).length > 0) await this._requireDek(dek, envelope);
|
|
440
442
|
if (!(sourceId in envelope.secrets) && Object.keys(envelope.secrets).length >= VAULT_LIMITS.secrets) {
|
|
441
443
|
throw new VaultError(`A vault holds at most ${VAULT_LIMITS.secrets} secrets.`, "invalid-input");
|
|
442
444
|
}
|
|
@@ -489,19 +491,31 @@ var Vault = class {
|
|
|
489
491
|
if (this._kdf === "pbkdf2") {
|
|
490
492
|
const kdf2 = { name: "PBKDF2-SHA256", iterations: this._iterations, salt: toBase64(salt) };
|
|
491
493
|
const kek2 = await this._derivePbkdf2(password, salt, this._iterations);
|
|
492
|
-
return { v: 1, kdf: kdf2, dek: await this._seal(kek2, dek, aadDekV1(kdf2)), secrets, createdAt };
|
|
494
|
+
return { v: 1, kdf: kdf2, dek: await this._seal(kek2, dek, aadDekV1(kdf2)), secrets, dekCheck: await this._sealDekCheck(dek), createdAt };
|
|
493
495
|
}
|
|
494
496
|
const kdf = { name: "scrypt", ...this._scrypt, salt: toBase64(salt) };
|
|
495
497
|
const kek = await this._deriveScrypt(password, salt, kdf);
|
|
496
|
-
return { v: 2, kdf, dek: await this._seal(kek, dek, aadDekV2(kdf)), secrets, passkeys, createdAt };
|
|
498
|
+
return { v: 2, kdf, dek: await this._seal(kek, dek, aadDekV2(kdf)), secrets, dekCheck: await this._sealDekCheck(dek), passkeys, createdAt };
|
|
499
|
+
}
|
|
500
|
+
/** The DEK check box: {@link DEK_CHECK} sealed under `dek`. */
|
|
501
|
+
async _sealDekCheck(dek) {
|
|
502
|
+
return this._seal(await this._importDek(dek), new TextEncoder().encode(DEK_CHECK), AAD_DEK_CHECK);
|
|
497
503
|
}
|
|
498
504
|
/**
|
|
499
|
-
* The caller's DEK must open this envelope's
|
|
500
|
-
*
|
|
505
|
+
* The caller's DEK must open this envelope's DEK check (or, in an envelope written before it, its
|
|
506
|
+
* first secret) — it is the key the password protects, not any 32 bytes. An old empty envelope has
|
|
507
|
+
* nothing to prove it with, so it is refused rather than trusted.
|
|
501
508
|
*/
|
|
502
509
|
async _requireDek(dek, envelope) {
|
|
503
510
|
const ids = Object.keys(envelope.secrets);
|
|
504
511
|
const key = await this._importDek(dek);
|
|
512
|
+
if (envelope.dekCheck !== void 0) {
|
|
513
|
+
const check = await this._open(key, envelope.dekCheck, AAD_DEK_CHECK, "locked");
|
|
514
|
+
const ok = new TextDecoder().decode(check) === DEK_CHECK;
|
|
515
|
+
(0, import_core.zeroize)(check);
|
|
516
|
+
if (!ok) throw new VaultError("The vault key does not open this entry; lock and unlock again.", "locked");
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
505
519
|
if (ids.length === 0) throw new VaultError("Add a secret to the vault before a passkey: an empty vault cannot prove the key is its own.", "invalid-input");
|
|
506
520
|
const probe = await this._open(key, envelope.secrets[ids[0]], aadSecret(ids[0]), "locked");
|
|
507
521
|
(0, import_core.zeroize)(probe);
|
|
@@ -571,13 +585,13 @@ function isEnvelopeV1(x) {
|
|
|
571
585
|
if (typeof x !== "object" || x === null) return false;
|
|
572
586
|
const e = x;
|
|
573
587
|
const kdf = e.kdf;
|
|
574
|
-
return e.v === 1 && typeof kdf === "object" && kdf !== null && kdf.name === "PBKDF2-SHA256" && Number.isInteger(kdf.iterations) && typeof kdf.salt === "string" && isBox(e.dek) && typeof e.secrets === "object" && e.secrets !== null && Object.values(e.secrets).every(isBox);
|
|
588
|
+
return e.v === 1 && typeof kdf === "object" && kdf !== null && kdf.name === "PBKDF2-SHA256" && Number.isInteger(kdf.iterations) && typeof kdf.salt === "string" && isBox(e.dek) && typeof e.secrets === "object" && e.secrets !== null && Object.values(e.secrets).every(isBox) && (e.dekCheck === void 0 || isBox(e.dekCheck));
|
|
575
589
|
}
|
|
576
590
|
function isEnvelopeV2(x) {
|
|
577
591
|
if (typeof x !== "object" || x === null) return false;
|
|
578
592
|
const e = x;
|
|
579
593
|
const kdf = e.kdf;
|
|
580
|
-
return e.v === 2 && typeof kdf === "object" && kdf !== null && kdf.name === "scrypt" && Number.isInteger(kdf.N) && Number.isInteger(kdf.r) && Number.isInteger(kdf.p) && typeof kdf.salt === "string" && isBox(e.dek) && typeof e.secrets === "object" && e.secrets !== null && Object.values(e.secrets).every(isBox) && Array.isArray(e.passkeys) && e.passkeys.every((p) => typeof p === "object" && p !== null && typeof p.id === "string" && typeof p.label === "string" && isBox(p.dek));
|
|
594
|
+
return e.v === 2 && typeof kdf === "object" && kdf !== null && kdf.name === "scrypt" && Number.isInteger(kdf.N) && Number.isInteger(kdf.r) && Number.isInteger(kdf.p) && typeof kdf.salt === "string" && isBox(e.dek) && typeof e.secrets === "object" && e.secrets !== null && Object.values(e.secrets).every(isBox) && (e.dekCheck === void 0 || isBox(e.dekCheck)) && Array.isArray(e.passkeys) && e.passkeys.every((p) => typeof p === "object" && p !== null && typeof p.id === "string" && typeof p.label === "string" && isBox(p.dek));
|
|
581
595
|
}
|
|
582
596
|
function isBox(x) {
|
|
583
597
|
return typeof x === "object" && x !== null && typeof x.iv === "string" && typeof x.data === "string";
|
|
@@ -592,7 +606,7 @@ function envelopeProblem(e) {
|
|
|
592
606
|
if (secrets.length > VAULT_LIMITS.secrets) return `${secrets.length} secrets > ${VAULT_LIMITS.secrets}`;
|
|
593
607
|
const passkeys = e.v === 2 ? e.passkeys : [];
|
|
594
608
|
if (passkeys.length > VAULT_LIMITS.passkeys) return `${passkeys.length} passkeys > ${VAULT_LIMITS.passkeys}`;
|
|
595
|
-
for (const box of [e.dek, ...secrets, ...passkeys.map((p) => p.dek)]) {
|
|
609
|
+
for (const box of [e.dek, ...e.dekCheck ? [e.dekCheck] : [], ...secrets, ...passkeys.map((p) => p.dek)]) {
|
|
596
610
|
if (box.iv.length > VAULT_LIMITS.boxChars || box.data.length > VAULT_LIMITS.boxChars) return `a sealed box above ${VAULT_LIMITS.boxChars} characters`;
|
|
597
611
|
}
|
|
598
612
|
if (JSON.stringify(e).length > VAULT_LIMITS.envelopeChars) return `envelope above ${VAULT_LIMITS.envelopeChars} characters`;
|
|
@@ -1828,6 +1842,12 @@ function outgrown(shown, now) {
|
|
|
1828
1842
|
if ("gasPrice" in now) return shown.gasPrice === void 0 || now.gasPrice > big(shown.gasPrice);
|
|
1829
1843
|
return shown.maxFeePerGas === void 0 || now.base + now.tip > big(shown.maxFeePerGas);
|
|
1830
1844
|
}
|
|
1845
|
+
var STALE_FEE_FACTOR = 4n;
|
|
1846
|
+
function overpriced(shown, fresh) {
|
|
1847
|
+
if (shown.gasPrice !== void 0 && fresh.gasPrice !== void 0) return big(shown.gasPrice) > STALE_FEE_FACTOR * big(fresh.gasPrice);
|
|
1848
|
+
if (shown.maxFeePerGas !== void 0 && fresh.maxFeePerGas !== void 0) return big(shown.maxFeePerGas) > STALE_FEE_FACTOR * big(fresh.maxFeePerGas);
|
|
1849
|
+
return false;
|
|
1850
|
+
}
|
|
1831
1851
|
async function prepareTransaction(deps, network, from, tx) {
|
|
1832
1852
|
const call = { from, to: tx.to, value: hex(BigInt(tx.value)), ...tx.data ? { data: tx.data } : {} };
|
|
1833
1853
|
const [nonceHex, block, gasHex] = await Promise.all([
|
|
@@ -1873,6 +1893,8 @@ function createSignHandler(deps) {
|
|
|
1873
1893
|
await deps.approvals.request({ origin, chain: network.caip2, kind: info.kind, payload: { ...payload, prepared: shown, repriced: true } });
|
|
1874
1894
|
continue;
|
|
1875
1895
|
}
|
|
1896
|
+
const fresh = withFees(network.chainId, nonce, big(shown.gasLimit), fees);
|
|
1897
|
+
if (overpriced(shown, fresh)) shown = fresh;
|
|
1876
1898
|
const handle2 = await deps.signerFor(info.account, network);
|
|
1877
1899
|
let raw;
|
|
1878
1900
|
try {
|
|
@@ -2129,13 +2151,14 @@ var ACTIVE_STATUSES = /* @__PURE__ */ new Set(["pending", "action-required", "re
|
|
|
2129
2151
|
function parseSwapId(id) {
|
|
2130
2152
|
if (!id.startsWith(`${import_protocol_swap2_core2.SWAP2_ID_PREFIX}.`)) return null;
|
|
2131
2153
|
const parts = id.slice(import_protocol_swap2_core2.SWAP2_ID_PREFIX.length + 1).split(".");
|
|
2132
|
-
if (parts.length < 2 || parts.length >
|
|
2154
|
+
if (parts.length < 2 || parts.length > 5 || !parts[0] || !parts[1]) return null;
|
|
2155
|
+
if (parts[4] !== void 0 && (parts[4] !== "ok" || !parts[3])) return null;
|
|
2133
2156
|
const provider = decodeURIComponent(parts[0]);
|
|
2134
2157
|
const intentId = decodeURIComponent(parts[1]);
|
|
2135
2158
|
const sourceTxHash = parts[2] ? decodeURIComponent(parts[2]) : void 0;
|
|
2136
2159
|
const destTxHash = parts[3] ? decodeURIComponent(parts[3]) : void 0;
|
|
2137
2160
|
if (destTxHash && !sourceTxHash) return null;
|
|
2138
|
-
return { provider, intentId, ...sourceTxHash ? { sourceTxHash } : {}, ...destTxHash ? { destTxHash } : {} };
|
|
2161
|
+
return { provider, intentId, ...sourceTxHash ? { sourceTxHash } : {}, ...destTxHash ? { destTxHash } : {}, ...parts[4] !== void 0 ? { destTxConfirmed: true } : {} };
|
|
2139
2162
|
}
|
|
2140
2163
|
var SwapsStore = class {
|
|
2141
2164
|
constructor(storage) {
|