@veridex/sdk 1.1.0 → 1.1.1
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/auth/prepareAuth.js +107 -32
- package/dist/auth/prepareAuth.js.map +1 -1
- package/dist/auth/prepareAuth.mjs +6 -6
- package/dist/chains/aptos/index.js.map +1 -1
- package/dist/chains/aptos/index.mjs +3 -3
- package/dist/chains/avalanche/index.js.map +1 -1
- package/dist/chains/avalanche/index.mjs +4 -4
- package/dist/chains/evm/index.d.mts +2 -2
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/evm/index.mjs +3 -3
- package/dist/chains/solana/index.js.map +1 -1
- package/dist/chains/solana/index.mjs +3 -3
- package/dist/chains/stacks/index.d.mts +1 -1
- package/dist/chains/stacks/index.js.map +1 -1
- package/dist/chains/stacks/index.mjs +3 -3
- package/dist/chains/starknet/index.d.mts +1 -1
- package/dist/chains/starknet/index.js.map +1 -1
- package/dist/chains/starknet/index.mjs +3 -3
- package/dist/chains/sui/index.d.mts +1 -1
- package/dist/chains/sui/index.js.map +1 -1
- package/dist/chains/sui/index.mjs +3 -3
- package/dist/{chunk-Q5O3M5LP.mjs → chunk-2TS375ET.mjs} +2 -2
- package/dist/{chunk-QT4ZZ4GM.mjs → chunk-5FDOTI5G.mjs} +2 -2
- package/dist/{chunk-5T6KPH7A.mjs → chunk-CSU4IV2F.mjs} +2 -2
- package/dist/{chunk-YCUJZ6Z7.mjs → chunk-CTYDGO6E.mjs} +63 -6
- package/dist/chunk-CTYDGO6E.mjs.map +1 -0
- package/dist/{chunk-SXXGTQIR.mjs → chunk-E3SU36C2.mjs} +2 -2
- package/dist/{chunk-NUWSMJFJ.mjs → chunk-EFIXFA6V.mjs} +2 -2
- package/dist/{chunk-MLXQHIH2.mjs → chunk-GM5DKEHD.mjs} +2 -2
- package/dist/{chunk-GWJRKDSA.mjs → chunk-GOWXQPTW.mjs} +3 -3
- package/dist/{chunk-OVMMTL6H.mjs → chunk-ICGB3AHI.mjs} +2 -2
- package/dist/{chunk-QDO6NQ7P.mjs → chunk-M3GUNREX.mjs} +20 -3
- package/dist/{chunk-QDO6NQ7P.mjs.map → chunk-M3GUNREX.mjs.map} +1 -1
- package/dist/{chunk-N4A2RMUN.mjs → chunk-PEGOXMBU.mjs} +2 -2
- package/dist/{chunk-X7BZMSPQ.mjs → chunk-RD6ZYUVG.mjs} +52 -30
- package/dist/chunk-RD6ZYUVG.mjs.map +1 -0
- package/dist/{chunk-F3YAGZSW.mjs → chunk-TPEP6XUA.mjs} +2 -2
- package/dist/{chunk-M3MM4YMF.mjs → chunk-UPO55SBK.mjs} +2 -2
- package/dist/{chunk-USDA5JTN.mjs → chunk-YBN2VC6E.mjs} +2 -2
- package/dist/{chunk-PDHZ5X5O.mjs → chunk-YYT3V7CI.mjs} +2 -2
- package/dist/constants.d.mts +2 -2
- package/dist/constants.js +51 -29
- package/dist/constants.js.map +1 -1
- package/dist/constants.mjs +1 -1
- package/dist/{index-DDalBhAm.d.mts → index-CySMITQ9.d.mts} +9 -6
- package/dist/index.d.mts +41 -13
- package/dist/index.js +445 -147
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +327 -127
- package/dist/index.mjs.map +1 -1
- package/dist/passkey.js +57 -4
- package/dist/passkey.js.map +1 -1
- package/dist/passkey.mjs +3 -3
- package/dist/payload.js.map +1 -1
- package/dist/payload.mjs +2 -2
- package/dist/portfolio-JA4OTF7Y.mjs +13 -0
- package/dist/queries/index.js +49 -27
- package/dist/queries/index.js.map +1 -1
- package/dist/queries/index.mjs +5 -5
- package/dist/{types-B7V5VNbO.d.mts → types-DWx-5jmz.d.mts} +12 -3
- package/dist/utils.js +49 -27
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +2 -2
- package/dist/wormhole.js.map +1 -1
- package/dist/wormhole.mjs +2 -2
- package/package.json +1 -1
- package/dist/chunk-X7BZMSPQ.mjs.map +0 -1
- package/dist/chunk-YCUJZ6Z7.mjs.map +0 -1
- package/dist/portfolio-V347KZOL.mjs +0 -13
- /package/dist/{chunk-Q5O3M5LP.mjs.map → chunk-2TS375ET.mjs.map} +0 -0
- /package/dist/{chunk-QT4ZZ4GM.mjs.map → chunk-5FDOTI5G.mjs.map} +0 -0
- /package/dist/{chunk-5T6KPH7A.mjs.map → chunk-CSU4IV2F.mjs.map} +0 -0
- /package/dist/{chunk-SXXGTQIR.mjs.map → chunk-E3SU36C2.mjs.map} +0 -0
- /package/dist/{chunk-NUWSMJFJ.mjs.map → chunk-EFIXFA6V.mjs.map} +0 -0
- /package/dist/{chunk-MLXQHIH2.mjs.map → chunk-GM5DKEHD.mjs.map} +0 -0
- /package/dist/{chunk-GWJRKDSA.mjs.map → chunk-GOWXQPTW.mjs.map} +0 -0
- /package/dist/{chunk-OVMMTL6H.mjs.map → chunk-ICGB3AHI.mjs.map} +0 -0
- /package/dist/{chunk-N4A2RMUN.mjs.map → chunk-PEGOXMBU.mjs.map} +0 -0
- /package/dist/{chunk-F3YAGZSW.mjs.map → chunk-TPEP6XUA.mjs.map} +0 -0
- /package/dist/{chunk-M3MM4YMF.mjs.map → chunk-UPO55SBK.mjs.map} +0 -0
- /package/dist/{chunk-USDA5JTN.mjs.map → chunk-YBN2VC6E.mjs.map} +0 -0
- /package/dist/{chunk-PDHZ5X5O.mjs.map → chunk-YYT3V7CI.mjs.map} +0 -0
- /package/dist/{portfolio-V347KZOL.mjs.map → portfolio-JA4OTF7Y.mjs.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -90,7 +90,7 @@ var init_constants = __esm({
|
|
|
90
90
|
SOLANA_DEVNET: 1,
|
|
91
91
|
GOERLI: 2,
|
|
92
92
|
BSC_TESTNET: 4,
|
|
93
|
-
|
|
93
|
+
POLYGON_AMOY: 10007,
|
|
94
94
|
AVALANCHE_FUJI: 6,
|
|
95
95
|
FANTOM_TESTNET: 10,
|
|
96
96
|
CELO_ALFAJORES: 14,
|
|
@@ -152,7 +152,7 @@ var init_constants = __esm({
|
|
|
152
152
|
SOLANA_DEVNET: 1,
|
|
153
153
|
GOERLI: 2,
|
|
154
154
|
BSC_TESTNET: 4,
|
|
155
|
-
|
|
155
|
+
POLYGON_AMOY: 10007,
|
|
156
156
|
AVALANCHE_FUJI: 6,
|
|
157
157
|
FANTOM_TESTNET: 10,
|
|
158
158
|
CELO_ALFAJORES: 14,
|
|
@@ -173,13 +173,12 @@ var init_constants = __esm({
|
|
|
173
173
|
chainId: 84532,
|
|
174
174
|
wormholeChainId: 10004,
|
|
175
175
|
rpcUrl: "https://sepolia.base.org",
|
|
176
|
-
// Public CORS-friendly RPC
|
|
177
176
|
explorerUrl: "https://sepolia.basescan.org",
|
|
178
177
|
isEvm: true,
|
|
179
178
|
contracts: {
|
|
180
|
-
hub: "
|
|
181
|
-
vaultFactory: "
|
|
182
|
-
vaultImplementation: "
|
|
179
|
+
hub: "0xD5D29b6EaeE6FF4b765e704298a7e48D22607059",
|
|
180
|
+
vaultFactory: "0xb25b73D5FeD5693dcd1Bb78f8e33387B59A022EC",
|
|
181
|
+
vaultImplementation: "0x2CB8397df988c1880d9e5cFfF65bfC22D7D90EE6",
|
|
183
182
|
wormholeCoreBridge: "0x79A1027a6A159502049F10906D333EC57E95F083",
|
|
184
183
|
tokenBridge: "0x86F55A04690fd7815A3D802bD587e83eA888B239"
|
|
185
184
|
}
|
|
@@ -192,8 +191,8 @@ var init_constants = __esm({
|
|
|
192
191
|
explorerUrl: "https://sepolia.etherscan.io",
|
|
193
192
|
isEvm: true,
|
|
194
193
|
contracts: {
|
|
195
|
-
vaultFactory: "
|
|
196
|
-
vaultImplementation: "
|
|
194
|
+
vaultFactory: "0x265c10763B4d16AD970bC3d7670c645e37f63AF4",
|
|
195
|
+
vaultImplementation: "0x942426C94652ebC48f4f404928016B95ADb1DA25",
|
|
197
196
|
wormholeCoreBridge: "0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78",
|
|
198
197
|
tokenBridge: "0xDB5492265f6038831E89f495670FF909aDe94bd9"
|
|
199
198
|
}
|
|
@@ -206,8 +205,8 @@ var init_constants = __esm({
|
|
|
206
205
|
explorerUrl: "https://sepolia-optimism.etherscan.io",
|
|
207
206
|
isEvm: true,
|
|
208
207
|
contracts: {
|
|
209
|
-
vaultFactory: "
|
|
210
|
-
vaultImplementation: "
|
|
208
|
+
vaultFactory: "0x3c5e4aCdC8Cd53ae5ae603B4c511885191fBb868",
|
|
209
|
+
vaultImplementation: "0xA45dBF322c5A3028687fEEB161603d3BCe02e119",
|
|
211
210
|
wormholeCoreBridge: "0x31377888146f3253211EFEf5c676D41ECe7D58Fe",
|
|
212
211
|
tokenBridge: "0x99737Ec4B815d816c49A385943baf0380e75c0Ac"
|
|
213
212
|
}
|
|
@@ -220,24 +219,52 @@ var init_constants = __esm({
|
|
|
220
219
|
explorerUrl: "https://sepolia.arbiscan.io",
|
|
221
220
|
isEvm: true,
|
|
222
221
|
contracts: {
|
|
223
|
-
vaultFactory: "
|
|
224
|
-
vaultImplementation: "
|
|
222
|
+
vaultFactory: "0xB9C3e6bad3c6f26956be4a4bb5a366376Fd3045D",
|
|
223
|
+
vaultImplementation: "0x8601881b94B68B09b485f407317686103d3CB681",
|
|
225
224
|
wormholeCoreBridge: "0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35",
|
|
226
225
|
tokenBridge: "0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e"
|
|
227
226
|
}
|
|
228
227
|
},
|
|
229
|
-
|
|
230
|
-
name: "
|
|
231
|
-
chainId:
|
|
232
|
-
wormholeChainId:
|
|
233
|
-
rpcUrl: "https://
|
|
234
|
-
explorerUrl: "https://
|
|
228
|
+
monadTestnet: {
|
|
229
|
+
name: "Monad Testnet",
|
|
230
|
+
chainId: 10143,
|
|
231
|
+
wormholeChainId: 10048,
|
|
232
|
+
rpcUrl: "https://testnet-rpc.monad.xyz",
|
|
233
|
+
explorerUrl: "https://testnet.monadexplorer.com",
|
|
234
|
+
isEvm: true,
|
|
235
|
+
contracts: {
|
|
236
|
+
vaultFactory: "0xbE9B9c39956448DA75Ac97E5e3dE17e34171660A",
|
|
237
|
+
vaultImplementation: "0x500853DCc54Fd1A707ec9d443032Bb7748f426d3",
|
|
238
|
+
wormholeCoreBridge: "0xBB73cB66C26740F31d1FabDC6b7A46a038A300dd",
|
|
239
|
+
tokenBridge: "0x0000000000000000000000000000000000000000"
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
avalancheFuji: {
|
|
243
|
+
name: "Avalanche Fuji",
|
|
244
|
+
chainId: 43113,
|
|
245
|
+
wormholeChainId: 6,
|
|
246
|
+
rpcUrl: "https://api.avax-test.network/ext/bc/C/rpc",
|
|
247
|
+
explorerUrl: "https://testnet.snowtrace.io",
|
|
248
|
+
isEvm: true,
|
|
249
|
+
contracts: {
|
|
250
|
+
vaultFactory: "0x50F2c37584823A6cc293bd0d7647D558d05CA4C1",
|
|
251
|
+
vaultImplementation: "0x53d4D3943d0E524836f0B1955AbB216449F538fF",
|
|
252
|
+
wormholeCoreBridge: "0x7bbcE28e64B3F8b84d876Ab298393c38ad7aac4C",
|
|
253
|
+
tokenBridge: "0x61E44E506Ca5659E6c0bba9b678586fA2d729756"
|
|
254
|
+
}
|
|
255
|
+
},
|
|
256
|
+
polygonAmoy: {
|
|
257
|
+
name: "Polygon Amoy",
|
|
258
|
+
chainId: 80002,
|
|
259
|
+
wormholeChainId: 10007,
|
|
260
|
+
rpcUrl: "https://rpc-amoy.polygon.technology",
|
|
261
|
+
explorerUrl: "https://amoy.polygonscan.com",
|
|
235
262
|
isEvm: true,
|
|
236
263
|
contracts: {
|
|
237
264
|
vaultFactory: "0x07F608AFf6d63b68029488b726d895c4Bb593038",
|
|
238
265
|
vaultImplementation: "0xD66153fccFB6731fB6c4944FbD607ba86A76a1f6",
|
|
239
|
-
wormholeCoreBridge: "
|
|
240
|
-
|
|
266
|
+
wormholeCoreBridge: "0x6b9C8671cdDC8dEab9c719bB87cBd3e782bA6a35",
|
|
267
|
+
tokenBridge: "0xC7A204bDBFe983FCD8d8E61D02b475D4073fF97e"
|
|
241
268
|
}
|
|
242
269
|
},
|
|
243
270
|
solanaDevnet: {
|
|
@@ -274,26 +301,21 @@ var init_constants = __esm({
|
|
|
274
301
|
explorerUrl: "https://suiscan.xyz/testnet",
|
|
275
302
|
isEvm: false,
|
|
276
303
|
contracts: {
|
|
277
|
-
hub: "
|
|
304
|
+
hub: "0x1f8f9b79561525275c2de4579a1e5243cfe789656ec666485b7737f4784c1bfc",
|
|
278
305
|
wormholeCoreBridge: "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
|
|
279
306
|
}
|
|
280
307
|
},
|
|
281
308
|
starknetSepolia: {
|
|
282
309
|
name: "Starknet Sepolia",
|
|
283
310
|
chainId: 0,
|
|
284
|
-
// Native Starknet chain ID (SN_SEPOLIA = 0x534e5f5345504f4c4941)
|
|
285
311
|
wormholeChainId: 50001,
|
|
286
|
-
|
|
287
|
-
rpcUrl: "https://starknet-sepolia.g.alchemy.com/starknet/version/rpc/v0_7/tsOnfTBZDKMXcUA26OED-",
|
|
312
|
+
rpcUrl: "https://starknet-sepolia-rpc.publicnode.com",
|
|
288
313
|
explorerUrl: "https://sepolia.starkscan.co",
|
|
289
314
|
isEvm: false,
|
|
290
315
|
contracts: {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
// Custom bridge contract (NOT Wormhole)
|
|
294
|
-
wormholeCoreBridge: "0x700488242f8f03248b2311edddc394f0408a18c36181446eabd265067809c83"
|
|
316
|
+
hub: "0x1c87ca930ad46a5fef167f2d03d6df5b1dd6cdb841955c059edabb0566ff2d6",
|
|
317
|
+
wormholeCoreBridge: "0x30280c19d413eef7515c479186f206498c7f5077e30cb7277ce753d35adab00"
|
|
295
318
|
},
|
|
296
|
-
// Hub chain ID that Starknet bridge validates (Base Sepolia = 10004)
|
|
297
319
|
hubChainId: 10004
|
|
298
320
|
}
|
|
299
321
|
};
|
|
@@ -580,6 +602,65 @@ var init_utils = __esm({
|
|
|
580
602
|
}
|
|
581
603
|
});
|
|
582
604
|
|
|
605
|
+
// src/core/relayerUrl.ts
|
|
606
|
+
function trimTrailingSlashes(value) {
|
|
607
|
+
return value.trim().replace(/\/+$/, "");
|
|
608
|
+
}
|
|
609
|
+
function normalizeRelayerOrigin(value) {
|
|
610
|
+
const trimmed = trimTrailingSlashes(value);
|
|
611
|
+
if (!trimmed) {
|
|
612
|
+
return "";
|
|
613
|
+
}
|
|
614
|
+
if (trimmed.startsWith("/")) {
|
|
615
|
+
return trimmed.replace(/\/api\/v1$/i, "");
|
|
616
|
+
}
|
|
617
|
+
try {
|
|
618
|
+
const url = new URL(trimmed);
|
|
619
|
+
url.pathname = url.pathname.replace(/\/api\/v1$/i, "").replace(/\/+$/, "");
|
|
620
|
+
return url.toString().replace(/\/+$/, "");
|
|
621
|
+
} catch {
|
|
622
|
+
return trimmed.replace(/\/api\/v1$/i, "");
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
function buildRelayerApiUrl(baseUrl, path) {
|
|
626
|
+
const normalizedPath = path.startsWith("/") ? path : `/${path}`;
|
|
627
|
+
const trimmed = trimTrailingSlashes(baseUrl);
|
|
628
|
+
if (!trimmed) {
|
|
629
|
+
return `${API_ROOT}${normalizedPath}`;
|
|
630
|
+
}
|
|
631
|
+
if (trimmed.startsWith("/")) {
|
|
632
|
+
if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
|
|
633
|
+
return `${trimmed}${normalizedPath}`;
|
|
634
|
+
}
|
|
635
|
+
return `${trimmed}${normalizedPath}`;
|
|
636
|
+
}
|
|
637
|
+
try {
|
|
638
|
+
const url = new URL(trimmed);
|
|
639
|
+
if (/\/api\/v1$/i.test(url.pathname) || /\/api\/auth\/relay$/i.test(url.pathname)) {
|
|
640
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
|
|
641
|
+
return url.toString();
|
|
642
|
+
}
|
|
643
|
+
if (!url.pathname || url.pathname === "/") {
|
|
644
|
+
url.pathname = `${API_ROOT}${normalizedPath}`;
|
|
645
|
+
return url.toString();
|
|
646
|
+
}
|
|
647
|
+
url.pathname = `${url.pathname.replace(/\/+$/, "")}${normalizedPath}`;
|
|
648
|
+
return url.toString();
|
|
649
|
+
} catch {
|
|
650
|
+
if (/\/api\/v1$/i.test(trimmed) || /\/api\/auth\/relay$/i.test(trimmed)) {
|
|
651
|
+
return `${trimmed}${normalizedPath}`;
|
|
652
|
+
}
|
|
653
|
+
return `${trimmed}${API_ROOT}${normalizedPath}`;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
var API_ROOT;
|
|
657
|
+
var init_relayerUrl = __esm({
|
|
658
|
+
"src/core/relayerUrl.ts"() {
|
|
659
|
+
"use strict";
|
|
660
|
+
API_ROOT = "/api/v1";
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
|
|
583
664
|
// src/core/PasskeyManager.ts
|
|
584
665
|
function detectRpId(forceLocal) {
|
|
585
666
|
if (typeof window === "undefined") return "localhost";
|
|
@@ -618,6 +699,7 @@ var init_PasskeyManager = __esm({
|
|
|
618
699
|
import_browser = require("@simplewebauthn/browser");
|
|
619
700
|
import_ethers2 = require("ethers");
|
|
620
701
|
init_utils();
|
|
702
|
+
init_relayerUrl();
|
|
621
703
|
VERIDEX_RP_ID = "veridex.network";
|
|
622
704
|
PasskeyManager = class _PasskeyManager {
|
|
623
705
|
config;
|
|
@@ -629,7 +711,7 @@ var init_PasskeyManager = __esm({
|
|
|
629
711
|
timeout: config.timeout ?? 6e4,
|
|
630
712
|
userVerification: config.userVerification ?? "required",
|
|
631
713
|
authenticatorAttachment: config.authenticatorAttachment ?? "platform",
|
|
632
|
-
relayerUrl: config.relayerUrl ?? ""
|
|
714
|
+
relayerUrl: normalizeRelayerOrigin(config.relayerUrl ?? "")
|
|
633
715
|
};
|
|
634
716
|
}
|
|
635
717
|
static isSupported() {
|
|
@@ -900,7 +982,7 @@ var init_PasskeyManager = __esm({
|
|
|
900
982
|
return false;
|
|
901
983
|
}
|
|
902
984
|
try {
|
|
903
|
-
const response = await fetch(
|
|
985
|
+
const response = await fetch(buildRelayerApiUrl(this.config.relayerUrl, "/credential"), {
|
|
904
986
|
method: "POST",
|
|
905
987
|
headers: { "Content-Type": "application/json" },
|
|
906
988
|
body: JSON.stringify({
|
|
@@ -932,7 +1014,7 @@ var init_PasskeyManager = __esm({
|
|
|
932
1014
|
}
|
|
933
1015
|
try {
|
|
934
1016
|
const response = await fetch(
|
|
935
|
-
|
|
1017
|
+
buildRelayerApiUrl(this.config.relayerUrl, `/credential/by-id/${encodeURIComponent(credentialId)}`)
|
|
936
1018
|
);
|
|
937
1019
|
if (!response.ok) {
|
|
938
1020
|
return null;
|
|
@@ -971,7 +1053,7 @@ var init_PasskeyManager = __esm({
|
|
|
971
1053
|
}
|
|
972
1054
|
try {
|
|
973
1055
|
const response = await fetch(
|
|
974
|
-
|
|
1056
|
+
buildRelayerApiUrl(this.config.relayerUrl, `/credential/${encodeURIComponent(keyHash)}`)
|
|
975
1057
|
);
|
|
976
1058
|
if (!response.ok) {
|
|
977
1059
|
return null;
|
|
@@ -2228,6 +2310,15 @@ var init_featureFlags = __esm({
|
|
|
2228
2310
|
});
|
|
2229
2311
|
|
|
2230
2312
|
// src/presets.ts
|
|
2313
|
+
function configureDefaultRpcUrls(overrides) {
|
|
2314
|
+
for (const key of Object.keys(_rpcOverrides)) {
|
|
2315
|
+
delete _rpcOverrides[key];
|
|
2316
|
+
}
|
|
2317
|
+
Object.assign(_rpcOverrides, overrides);
|
|
2318
|
+
}
|
|
2319
|
+
function getRpcUrlOverride(chain, network) {
|
|
2320
|
+
return _rpcOverrides[chain]?.[network];
|
|
2321
|
+
}
|
|
2231
2322
|
function getChainConfig(chain, network = "testnet") {
|
|
2232
2323
|
const preset = CHAIN_PRESETS[chain];
|
|
2233
2324
|
if (!preset) {
|
|
@@ -2235,7 +2326,12 @@ function getChainConfig(chain, network = "testnet") {
|
|
|
2235
2326
|
`Unknown chain: "${chain}". Supported chains: ${Object.keys(CHAIN_PRESETS).join(", ")}`
|
|
2236
2327
|
);
|
|
2237
2328
|
}
|
|
2238
|
-
|
|
2329
|
+
const config = preset[network];
|
|
2330
|
+
const rpcOverride = getRpcUrlOverride(chain, network);
|
|
2331
|
+
if (rpcOverride) {
|
|
2332
|
+
return { ...config, rpcUrl: rpcOverride };
|
|
2333
|
+
}
|
|
2334
|
+
return config;
|
|
2239
2335
|
}
|
|
2240
2336
|
function getChainPreset(chain) {
|
|
2241
2337
|
const preset = CHAIN_PRESETS[chain];
|
|
@@ -2270,7 +2366,7 @@ function getDefaultHub(network = "testnet") {
|
|
|
2270
2366
|
const primary = getEffectivePrimaryHub();
|
|
2271
2367
|
return CHAIN_PRESETS[primary][network];
|
|
2272
2368
|
}
|
|
2273
|
-
var CHAIN_NAMES, CHAIN_PRESETS;
|
|
2369
|
+
var CHAIN_NAMES, CHAIN_PRESETS, _rpcOverrides;
|
|
2274
2370
|
var init_presets = __esm({
|
|
2275
2371
|
"src/presets.ts"() {
|
|
2276
2372
|
"use strict";
|
|
@@ -2930,7 +3026,7 @@ var init_presets = __esm({
|
|
|
2930
3026
|
chainId: 0,
|
|
2931
3027
|
wormholeChainId: 50001,
|
|
2932
3028
|
// Custom bridge (non-Wormhole)
|
|
2933
|
-
rpcUrl: "https://starknet-sepolia.
|
|
3029
|
+
rpcUrl: "https://starknet-sepolia-rpc.publicnode.com",
|
|
2934
3030
|
explorerUrl: "https://sepolia.starkscan.co",
|
|
2935
3031
|
isEvm: false,
|
|
2936
3032
|
contracts: {
|
|
@@ -3029,6 +3125,7 @@ var init_presets = __esm({
|
|
|
3029
3125
|
}
|
|
3030
3126
|
}
|
|
3031
3127
|
};
|
|
3128
|
+
_rpcOverrides = {};
|
|
3032
3129
|
}
|
|
3033
3130
|
});
|
|
3034
3131
|
|
|
@@ -4143,6 +4240,7 @@ __export(src_exports, {
|
|
|
4143
4240
|
calculatePercentage: () => calculatePercentage,
|
|
4144
4241
|
computeKeyHash: () => computeKeyHash,
|
|
4145
4242
|
computeSessionKeyHash: () => computeSessionKeyHash,
|
|
4243
|
+
configureDefaultRpcUrls: () => configureDefaultRpcUrls,
|
|
4146
4244
|
createAuditEntry: () => createAuditEntry,
|
|
4147
4245
|
createChainClient: () => createChainClient,
|
|
4148
4246
|
createChainDetector: () => createChainDetector,
|
|
@@ -4213,6 +4311,7 @@ __export(src_exports, {
|
|
|
4213
4311
|
getExplorerUrl: () => getExplorerUrl,
|
|
4214
4312
|
getFeatureFlags: () => getFeatureFlags,
|
|
4215
4313
|
getHubChains: () => getHubChains,
|
|
4314
|
+
getRpcUrlOverride: () => getRpcUrlOverride,
|
|
4216
4315
|
getSequenceFromTxReceipt: () => getSequenceFromTxReceipt,
|
|
4217
4316
|
getStacksContractPrincipal: () => getContractPrincipal,
|
|
4218
4317
|
getStacksExplorerAddressUrl: () => getStacksExplorerAddressUrl,
|
|
@@ -5507,6 +5606,7 @@ var CrossChainManager = class {
|
|
|
5507
5606
|
var crossChainManager = new CrossChainManager();
|
|
5508
5607
|
|
|
5509
5608
|
// src/core/RelayerClient.ts
|
|
5609
|
+
init_relayerUrl();
|
|
5510
5610
|
var DEFAULT_CONFIG2 = {
|
|
5511
5611
|
apiKey: "",
|
|
5512
5612
|
timeoutMs: 3e4,
|
|
@@ -5516,7 +5616,7 @@ var RelayerClient = class _RelayerClient {
|
|
|
5516
5616
|
baseUrl;
|
|
5517
5617
|
config;
|
|
5518
5618
|
constructor(config) {
|
|
5519
|
-
this.baseUrl = config.baseUrl
|
|
5619
|
+
this.baseUrl = normalizeRelayerOrigin(config.baseUrl);
|
|
5520
5620
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
5521
5621
|
}
|
|
5522
5622
|
// ========================================================================
|
|
@@ -5783,6 +5883,7 @@ var RelayerClient = class _RelayerClient {
|
|
|
5783
5883
|
* Make an HTTP request to the relayer
|
|
5784
5884
|
*/
|
|
5785
5885
|
async fetch(path, options = {}) {
|
|
5886
|
+
const resolvedUrl = path.startsWith("/api/v1/") ? buildRelayerApiUrl(this.baseUrl, path.replace(/^\/api\/v1/, "")) : `${this.baseUrl}${path}`;
|
|
5786
5887
|
const headers = {
|
|
5787
5888
|
"Content-Type": "application/json",
|
|
5788
5889
|
"User-Agent": `@veridex/sdk/${_RelayerClient.SDK_VERSION}`,
|
|
@@ -5796,7 +5897,7 @@ var RelayerClient = class _RelayerClient {
|
|
|
5796
5897
|
let lastError = null;
|
|
5797
5898
|
for (let attempt = 0; attempt <= this.config.maxRetries; attempt++) {
|
|
5798
5899
|
try {
|
|
5799
|
-
const response = await fetch(
|
|
5900
|
+
const response = await fetch(resolvedUrl, {
|
|
5800
5901
|
...options,
|
|
5801
5902
|
headers,
|
|
5802
5903
|
signal: controller.signal
|
|
@@ -15369,13 +15470,14 @@ function inferBackupEligibility(platform) {
|
|
|
15369
15470
|
}
|
|
15370
15471
|
|
|
15371
15472
|
// src/core/CredentialManager.ts
|
|
15473
|
+
init_relayerUrl();
|
|
15372
15474
|
var DEFAULT_STORAGE_KEY = "veridex_credential_metadata";
|
|
15373
15475
|
var CredentialManager = class {
|
|
15374
15476
|
config;
|
|
15375
15477
|
constructor(config = {}) {
|
|
15376
15478
|
this.config = {
|
|
15377
15479
|
storageKey: config.storageKey ?? DEFAULT_STORAGE_KEY,
|
|
15378
|
-
relayerUrl: config.relayerUrl ?? ""
|
|
15480
|
+
relayerUrl: normalizeRelayerOrigin(config.relayerUrl ?? "")
|
|
15379
15481
|
};
|
|
15380
15482
|
}
|
|
15381
15483
|
// ========================================================================
|
|
@@ -15523,7 +15625,7 @@ var CredentialManager = class {
|
|
|
15523
15625
|
const managed = this.getCredential(credentialId);
|
|
15524
15626
|
if (!managed) return false;
|
|
15525
15627
|
try {
|
|
15526
|
-
const response = await fetch(
|
|
15628
|
+
const response = await fetch(buildRelayerApiUrl(this.config.relayerUrl, "/credential/metadata"), {
|
|
15527
15629
|
method: "PUT",
|
|
15528
15630
|
headers: { "Content-Type": "application/json" },
|
|
15529
15631
|
body: JSON.stringify({
|
|
@@ -15549,7 +15651,10 @@ var CredentialManager = class {
|
|
|
15549
15651
|
if (!this.config.relayerUrl) return null;
|
|
15550
15652
|
try {
|
|
15551
15653
|
const response = await fetch(
|
|
15552
|
-
|
|
15654
|
+
buildRelayerApiUrl(
|
|
15655
|
+
this.config.relayerUrl,
|
|
15656
|
+
`/credential/metadata?keyHash=${encodeURIComponent(keyHash)}`
|
|
15657
|
+
)
|
|
15553
15658
|
);
|
|
15554
15659
|
if (!response.ok) return null;
|
|
15555
15660
|
const data = await response.json();
|
|
@@ -15671,9 +15776,10 @@ var CredentialManager = class {
|
|
|
15671
15776
|
|
|
15672
15777
|
// src/core/CrossOriginAuth.ts
|
|
15673
15778
|
init_PasskeyManager();
|
|
15779
|
+
init_relayerUrl();
|
|
15674
15780
|
init_PasskeyManager();
|
|
15675
15781
|
var DEFAULT_AUTH_PORTAL_URL = "https://auth.veridex.network";
|
|
15676
|
-
var DEFAULT_RELAYER_URL = "https://
|
|
15782
|
+
var DEFAULT_RELAYER_URL = "https://relayer.veridex.network";
|
|
15677
15783
|
var AUTH_MESSAGE_TYPES = {
|
|
15678
15784
|
AUTH_REQUEST: "VERIDEX_AUTH_REQUEST",
|
|
15679
15785
|
AUTH_RESPONSE: "VERIDEX_AUTH_RESPONSE",
|
|
@@ -15685,7 +15791,7 @@ var CrossOriginAuth = class {
|
|
|
15685
15791
|
this.config = {
|
|
15686
15792
|
rpId: config.rpId ?? VERIDEX_RP_ID,
|
|
15687
15793
|
authPortalUrl: config.authPortalUrl ?? DEFAULT_AUTH_PORTAL_URL,
|
|
15688
|
-
relayerUrl: config.relayerUrl ?? DEFAULT_RELAYER_URL,
|
|
15794
|
+
relayerUrl: normalizeRelayerOrigin(config.relayerUrl ?? DEFAULT_RELAYER_URL),
|
|
15689
15795
|
mode: config.mode ?? "popup",
|
|
15690
15796
|
popupFeatures: config.popupFeatures ?? "width=500,height=600,left=100,top=100",
|
|
15691
15797
|
timeout: config.timeout ?? 12e4,
|
|
@@ -15902,7 +16008,8 @@ var CrossOriginAuth = class {
|
|
|
15902
16008
|
return bytes;
|
|
15903
16009
|
}
|
|
15904
16010
|
async requestServerSessionChallenge(options) {
|
|
15905
|
-
const
|
|
16011
|
+
const challengeUrl = buildRelayerApiUrl(this.config.relayerUrl, "/session/challenge");
|
|
16012
|
+
const response = await fetch(challengeUrl, {
|
|
15906
16013
|
method: "POST",
|
|
15907
16014
|
headers: { "Content-Type": "application/json" },
|
|
15908
16015
|
body: JSON.stringify({
|
|
@@ -15948,7 +16055,7 @@ var CrossOriginAuth = class {
|
|
|
15948
16055
|
if (!session.serverChallengeId) {
|
|
15949
16056
|
throw new Error("Session must include a relayer-issued serverChallengeId");
|
|
15950
16057
|
}
|
|
15951
|
-
const response = await fetch(
|
|
16058
|
+
const response = await fetch(buildRelayerApiUrl(this.config.relayerUrl, "/session/create"), {
|
|
15952
16059
|
method: "POST",
|
|
15953
16060
|
headers: { "Content-Type": "application/json" },
|
|
15954
16061
|
body: JSON.stringify({
|
|
@@ -15971,7 +16078,9 @@ var CrossOriginAuth = class {
|
|
|
15971
16078
|
* Returns the session details if valid, null if expired/revoked.
|
|
15972
16079
|
*/
|
|
15973
16080
|
async validateServerSession(sessionId) {
|
|
15974
|
-
const response = await fetch(
|
|
16081
|
+
const response = await fetch(
|
|
16082
|
+
buildRelayerApiUrl(this.config.relayerUrl, `/session/${encodeURIComponent(sessionId)}`)
|
|
16083
|
+
);
|
|
15975
16084
|
if (!response.ok) {
|
|
15976
16085
|
return null;
|
|
15977
16086
|
}
|
|
@@ -15985,9 +16094,12 @@ var CrossOriginAuth = class {
|
|
|
15985
16094
|
* Revoke a server session token.
|
|
15986
16095
|
*/
|
|
15987
16096
|
async revokeServerSession(sessionId) {
|
|
15988
|
-
const response = await fetch(
|
|
15989
|
-
|
|
15990
|
-
|
|
16097
|
+
const response = await fetch(
|
|
16098
|
+
buildRelayerApiUrl(this.config.relayerUrl, `/session/${encodeURIComponent(sessionId)}`),
|
|
16099
|
+
{
|
|
16100
|
+
method: "DELETE"
|
|
16101
|
+
}
|
|
16102
|
+
);
|
|
15991
16103
|
return response.ok;
|
|
15992
16104
|
}
|
|
15993
16105
|
/**
|
|
@@ -16547,39 +16659,44 @@ var IndexedDBSessionStorage = class {
|
|
|
16547
16659
|
);
|
|
16548
16660
|
}
|
|
16549
16661
|
}
|
|
16662
|
+
async decryptSession(stored) {
|
|
16663
|
+
const key = await this.getEncryptionKey();
|
|
16664
|
+
const encryptedPrivateKey = new Uint8Array(stored.encryptedPrivateKey);
|
|
16665
|
+
const privateKey = await decrypt(encryptedPrivateKey, key);
|
|
16666
|
+
return {
|
|
16667
|
+
keyHash: stored.keyHash,
|
|
16668
|
+
publicKey: new Uint8Array(stored.publicKey),
|
|
16669
|
+
privateKey,
|
|
16670
|
+
expiry: stored.expiry,
|
|
16671
|
+
maxValue: BigInt(stored.maxValue),
|
|
16672
|
+
chainScopes: stored.chainScopes ?? [],
|
|
16673
|
+
userKeyHash: stored.userKeyHash
|
|
16674
|
+
};
|
|
16675
|
+
}
|
|
16676
|
+
async pruneExpiredSessions(records) {
|
|
16677
|
+
const now = Date.now();
|
|
16678
|
+
const validRecords = records.filter((record) => record.expiry > now);
|
|
16679
|
+
const expiredRecords = records.filter((record) => record.expiry <= now);
|
|
16680
|
+
if (expiredRecords.length > 0) {
|
|
16681
|
+
await Promise.all(expiredRecords.map((record) => this.remove(record.keyHash)));
|
|
16682
|
+
}
|
|
16683
|
+
return validRecords.sort((left, right) => right.savedAt - left.savedAt);
|
|
16684
|
+
}
|
|
16550
16685
|
/**
|
|
16551
|
-
* Load
|
|
16686
|
+
* Load a session (decrypts private key)
|
|
16552
16687
|
*/
|
|
16553
|
-
async load() {
|
|
16688
|
+
async load(keyHash) {
|
|
16554
16689
|
try {
|
|
16555
16690
|
await this.initialize();
|
|
16556
16691
|
if (!this.db) {
|
|
16557
16692
|
throw new Error("Database not initialized");
|
|
16558
16693
|
}
|
|
16559
|
-
const
|
|
16560
|
-
|
|
16561
|
-
return null;
|
|
16562
|
-
}
|
|
16563
|
-
const now = Date.now();
|
|
16564
|
-
const validSessions = allSessions.filter((s) => s.expiry > now).sort((a, b) => b.savedAt - a.savedAt);
|
|
16694
|
+
const sessions = keyHash ? await this.getSessionByKeyHash(keyHash) : await this.getAllSessions();
|
|
16695
|
+
const validSessions = await this.pruneExpiredSessions(sessions);
|
|
16565
16696
|
if (validSessions.length === 0) {
|
|
16566
|
-
await this.clear();
|
|
16567
16697
|
return null;
|
|
16568
16698
|
}
|
|
16569
|
-
|
|
16570
|
-
const key = await this.getEncryptionKey();
|
|
16571
|
-
const encryptedPrivateKey = new Uint8Array(stored.encryptedPrivateKey);
|
|
16572
|
-
const privateKey = await decrypt(encryptedPrivateKey, key);
|
|
16573
|
-
const session = {
|
|
16574
|
-
keyHash: stored.keyHash,
|
|
16575
|
-
publicKey: new Uint8Array(stored.publicKey),
|
|
16576
|
-
privateKey,
|
|
16577
|
-
expiry: stored.expiry,
|
|
16578
|
-
maxValue: BigInt(stored.maxValue),
|
|
16579
|
-
chainScopes: stored.chainScopes,
|
|
16580
|
-
userKeyHash: stored.userKeyHash
|
|
16581
|
-
};
|
|
16582
|
-
return session;
|
|
16699
|
+
return this.decryptSession(validSessions[0]);
|
|
16583
16700
|
} catch (error) {
|
|
16584
16701
|
if (error instanceof SessionError) {
|
|
16585
16702
|
throw error;
|
|
@@ -16612,6 +16729,75 @@ var IndexedDBSessionStorage = class {
|
|
|
16612
16729
|
};
|
|
16613
16730
|
});
|
|
16614
16731
|
}
|
|
16732
|
+
async getSessionByKeyHash(keyHash) {
|
|
16733
|
+
if (!this.db) {
|
|
16734
|
+
return [];
|
|
16735
|
+
}
|
|
16736
|
+
return new Promise((resolve, reject) => {
|
|
16737
|
+
const transaction = this.db.transaction([STORE_NAME], "readonly");
|
|
16738
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
16739
|
+
const request = store.get(keyHash);
|
|
16740
|
+
request.onsuccess = () => {
|
|
16741
|
+
resolve(request.result ? [request.result] : []);
|
|
16742
|
+
};
|
|
16743
|
+
request.onerror = () => {
|
|
16744
|
+
reject(new SessionError(
|
|
16745
|
+
"Failed to get session",
|
|
16746
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
16747
|
+
request.error
|
|
16748
|
+
));
|
|
16749
|
+
};
|
|
16750
|
+
});
|
|
16751
|
+
}
|
|
16752
|
+
async loadAll() {
|
|
16753
|
+
try {
|
|
16754
|
+
await this.initialize();
|
|
16755
|
+
if (!this.db) {
|
|
16756
|
+
return [];
|
|
16757
|
+
}
|
|
16758
|
+
const records = await this.pruneExpiredSessions(await this.getAllSessions());
|
|
16759
|
+
return Promise.all(records.map((record) => this.decryptSession(record)));
|
|
16760
|
+
} catch (error) {
|
|
16761
|
+
if (error instanceof SessionError) {
|
|
16762
|
+
throw error;
|
|
16763
|
+
}
|
|
16764
|
+
throw new SessionError(
|
|
16765
|
+
"Failed to load sessions",
|
|
16766
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
16767
|
+
error
|
|
16768
|
+
);
|
|
16769
|
+
}
|
|
16770
|
+
}
|
|
16771
|
+
async remove(keyHash) {
|
|
16772
|
+
try {
|
|
16773
|
+
await this.initialize();
|
|
16774
|
+
if (!this.db) {
|
|
16775
|
+
return;
|
|
16776
|
+
}
|
|
16777
|
+
return new Promise((resolve, reject) => {
|
|
16778
|
+
const transaction = this.db.transaction([STORE_NAME], "readwrite");
|
|
16779
|
+
const store = transaction.objectStore(STORE_NAME);
|
|
16780
|
+
const request = store.delete(keyHash);
|
|
16781
|
+
request.onsuccess = () => resolve();
|
|
16782
|
+
request.onerror = () => {
|
|
16783
|
+
reject(new SessionError(
|
|
16784
|
+
"Failed to remove session",
|
|
16785
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
16786
|
+
request.error
|
|
16787
|
+
));
|
|
16788
|
+
};
|
|
16789
|
+
});
|
|
16790
|
+
} catch (error) {
|
|
16791
|
+
if (error instanceof SessionError) {
|
|
16792
|
+
throw error;
|
|
16793
|
+
}
|
|
16794
|
+
throw new SessionError(
|
|
16795
|
+
"Failed to remove session",
|
|
16796
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
16797
|
+
error
|
|
16798
|
+
);
|
|
16799
|
+
}
|
|
16800
|
+
}
|
|
16615
16801
|
/**
|
|
16616
16802
|
* Clear all sessions
|
|
16617
16803
|
*/
|
|
@@ -16648,14 +16834,9 @@ var IndexedDBSessionStorage = class {
|
|
|
16648
16834
|
/**
|
|
16649
16835
|
* Check if any session exists
|
|
16650
16836
|
*/
|
|
16651
|
-
async exists() {
|
|
16837
|
+
async exists(keyHash) {
|
|
16652
16838
|
try {
|
|
16653
|
-
await this.
|
|
16654
|
-
if (!this.db) {
|
|
16655
|
-
return false;
|
|
16656
|
-
}
|
|
16657
|
-
const sessions = await this.getAllSessions();
|
|
16658
|
-
return sessions.length > 0;
|
|
16839
|
+
return await this.load(keyHash) !== null;
|
|
16659
16840
|
} catch {
|
|
16660
16841
|
return false;
|
|
16661
16842
|
}
|
|
@@ -16674,7 +16855,8 @@ var STORAGE_KEY_PREFIX = "veridex-session-";
|
|
|
16674
16855
|
var LocalStorageSessionStorage = class {
|
|
16675
16856
|
encryptionKey = null;
|
|
16676
16857
|
credentialId;
|
|
16677
|
-
|
|
16858
|
+
credentialHash;
|
|
16859
|
+
legacyStorageKey;
|
|
16678
16860
|
/**
|
|
16679
16861
|
* @param credentialId User's Passkey credential ID (for key derivation)
|
|
16680
16862
|
*/
|
|
@@ -16686,7 +16868,60 @@ var LocalStorageSessionStorage = class {
|
|
|
16686
16868
|
);
|
|
16687
16869
|
}
|
|
16688
16870
|
this.credentialId = credentialId;
|
|
16689
|
-
this.
|
|
16871
|
+
this.credentialHash = import_ethers20.ethers.keccak256(import_ethers20.ethers.toUtf8Bytes(credentialId));
|
|
16872
|
+
this.legacyStorageKey = STORAGE_KEY_PREFIX + this.credentialHash;
|
|
16873
|
+
}
|
|
16874
|
+
getSessionStorageKey(keyHash) {
|
|
16875
|
+
return `${STORAGE_KEY_PREFIX}${this.credentialHash}:${keyHash}`;
|
|
16876
|
+
}
|
|
16877
|
+
getSessionStoragePrefix() {
|
|
16878
|
+
return `${STORAGE_KEY_PREFIX}${this.credentialHash}:`;
|
|
16879
|
+
}
|
|
16880
|
+
async deserializeSession(stored) {
|
|
16881
|
+
const key = await this.getEncryptionKey();
|
|
16882
|
+
const encryptedPrivateKey = typeof stored.encryptedPrivateKey === "string" ? import_ethers20.ethers.getBytes(stored.encryptedPrivateKey) : new Uint8Array(stored.encryptedPrivateKey);
|
|
16883
|
+
const privateKey = await decrypt(encryptedPrivateKey, key);
|
|
16884
|
+
return {
|
|
16885
|
+
keyHash: stored.keyHash,
|
|
16886
|
+
publicKey: typeof stored.publicKey === "string" ? import_ethers20.ethers.getBytes(stored.publicKey) : new Uint8Array(stored.publicKey),
|
|
16887
|
+
privateKey,
|
|
16888
|
+
expiry: stored.expiry,
|
|
16889
|
+
maxValue: BigInt(stored.maxValue),
|
|
16890
|
+
chainScopes: stored.chainScopes ?? [],
|
|
16891
|
+
userKeyHash: stored.userKeyHash
|
|
16892
|
+
};
|
|
16893
|
+
}
|
|
16894
|
+
getRawRecords() {
|
|
16895
|
+
const records = [];
|
|
16896
|
+
const prefix = this.getSessionStoragePrefix();
|
|
16897
|
+
for (let index = 0; index < localStorage.length; index++) {
|
|
16898
|
+
const key = localStorage.key(index);
|
|
16899
|
+
if (!key || !key.startsWith(prefix)) {
|
|
16900
|
+
continue;
|
|
16901
|
+
}
|
|
16902
|
+
const value = localStorage.getItem(key);
|
|
16903
|
+
if (!value) {
|
|
16904
|
+
continue;
|
|
16905
|
+
}
|
|
16906
|
+
records.push(JSON.parse(value));
|
|
16907
|
+
}
|
|
16908
|
+
const legacyValue = localStorage.getItem(this.legacyStorageKey);
|
|
16909
|
+
if (legacyValue) {
|
|
16910
|
+
records.push(JSON.parse(legacyValue));
|
|
16911
|
+
}
|
|
16912
|
+
return records;
|
|
16913
|
+
}
|
|
16914
|
+
async getValidRecords() {
|
|
16915
|
+
const now = Date.now();
|
|
16916
|
+
const validRecords = [];
|
|
16917
|
+
for (const record of this.getRawRecords()) {
|
|
16918
|
+
if (record.expiry <= now) {
|
|
16919
|
+
await this.remove(record.keyHash);
|
|
16920
|
+
continue;
|
|
16921
|
+
}
|
|
16922
|
+
validRecords.push(record);
|
|
16923
|
+
}
|
|
16924
|
+
return validRecords.sort((left, right) => right.savedAt - left.savedAt);
|
|
16690
16925
|
}
|
|
16691
16926
|
/**
|
|
16692
16927
|
* Get or derive encryption key
|
|
@@ -16715,7 +16950,7 @@ var LocalStorageSessionStorage = class {
|
|
|
16715
16950
|
userKeyHash: session.userKeyHash,
|
|
16716
16951
|
savedAt: Date.now()
|
|
16717
16952
|
};
|
|
16718
|
-
localStorage.setItem(this.
|
|
16953
|
+
localStorage.setItem(this.getSessionStorageKey(session.keyHash), JSON.stringify(storageObject));
|
|
16719
16954
|
} catch (error) {
|
|
16720
16955
|
if (error instanceof SessionError) {
|
|
16721
16956
|
throw error;
|
|
@@ -16728,32 +16963,15 @@ var LocalStorageSessionStorage = class {
|
|
|
16728
16963
|
}
|
|
16729
16964
|
}
|
|
16730
16965
|
/**
|
|
16731
|
-
* Load
|
|
16966
|
+
* Load a session (decrypts private key)
|
|
16732
16967
|
*/
|
|
16733
|
-
async load() {
|
|
16968
|
+
async load(keyHash) {
|
|
16734
16969
|
try {
|
|
16735
|
-
const
|
|
16736
|
-
if (
|
|
16970
|
+
const records = keyHash ? (await this.getValidRecords()).filter((record) => record.keyHash === keyHash) : await this.getValidRecords();
|
|
16971
|
+
if (records.length === 0) {
|
|
16737
16972
|
return null;
|
|
16738
16973
|
}
|
|
16739
|
-
|
|
16740
|
-
if (stored.expiry <= Date.now()) {
|
|
16741
|
-
await this.clear();
|
|
16742
|
-
return null;
|
|
16743
|
-
}
|
|
16744
|
-
const key = await this.getEncryptionKey();
|
|
16745
|
-
const encryptedPrivateKey = import_ethers20.ethers.getBytes(stored.encryptedPrivateKey);
|
|
16746
|
-
const privateKey = await decrypt(encryptedPrivateKey, key);
|
|
16747
|
-
const session = {
|
|
16748
|
-
keyHash: stored.keyHash,
|
|
16749
|
-
publicKey: import_ethers20.ethers.getBytes(stored.publicKey),
|
|
16750
|
-
privateKey,
|
|
16751
|
-
expiry: stored.expiry,
|
|
16752
|
-
maxValue: BigInt(stored.maxValue),
|
|
16753
|
-
chainScopes: stored.chainScopes,
|
|
16754
|
-
userKeyHash: stored.userKeyHash
|
|
16755
|
-
};
|
|
16756
|
-
return session;
|
|
16974
|
+
return this.deserializeSession(records[0]);
|
|
16757
16975
|
} catch (error) {
|
|
16758
16976
|
await this.clear();
|
|
16759
16977
|
if (error instanceof SessionError) {
|
|
@@ -16766,12 +16984,55 @@ var LocalStorageSessionStorage = class {
|
|
|
16766
16984
|
);
|
|
16767
16985
|
}
|
|
16768
16986
|
}
|
|
16987
|
+
async loadAll() {
|
|
16988
|
+
try {
|
|
16989
|
+
const records = await this.getValidRecords();
|
|
16990
|
+
return Promise.all(records.map((record) => this.deserializeSession(record)));
|
|
16991
|
+
} catch (error) {
|
|
16992
|
+
await this.clear();
|
|
16993
|
+
if (error instanceof SessionError) {
|
|
16994
|
+
throw error;
|
|
16995
|
+
}
|
|
16996
|
+
throw new SessionError(
|
|
16997
|
+
"Failed to load sessions",
|
|
16998
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
16999
|
+
error
|
|
17000
|
+
);
|
|
17001
|
+
}
|
|
17002
|
+
}
|
|
17003
|
+
async remove(keyHash) {
|
|
17004
|
+
try {
|
|
17005
|
+
localStorage.removeItem(this.getSessionStorageKey(keyHash));
|
|
17006
|
+
const legacyValue = localStorage.getItem(this.legacyStorageKey);
|
|
17007
|
+
if (legacyValue) {
|
|
17008
|
+
const legacyRecord = JSON.parse(legacyValue);
|
|
17009
|
+
if (legacyRecord.keyHash === keyHash) {
|
|
17010
|
+
localStorage.removeItem(this.legacyStorageKey);
|
|
17011
|
+
}
|
|
17012
|
+
}
|
|
17013
|
+
} catch (error) {
|
|
17014
|
+
throw new SessionError(
|
|
17015
|
+
"Failed to remove session",
|
|
17016
|
+
"STORAGE_ERROR" /* STORAGE_ERROR */,
|
|
17017
|
+
error
|
|
17018
|
+
);
|
|
17019
|
+
}
|
|
17020
|
+
}
|
|
16769
17021
|
/**
|
|
16770
17022
|
* Clear all sessions
|
|
16771
17023
|
*/
|
|
16772
17024
|
async clear() {
|
|
16773
17025
|
try {
|
|
16774
|
-
|
|
17026
|
+
const keysToRemove = [];
|
|
17027
|
+
const prefix = this.getSessionStoragePrefix();
|
|
17028
|
+
for (let index = 0; index < localStorage.length; index++) {
|
|
17029
|
+
const key = localStorage.key(index);
|
|
17030
|
+
if (key && key.startsWith(prefix)) {
|
|
17031
|
+
keysToRemove.push(key);
|
|
17032
|
+
}
|
|
17033
|
+
}
|
|
17034
|
+
keysToRemove.forEach((key) => localStorage.removeItem(key));
|
|
17035
|
+
localStorage.removeItem(this.legacyStorageKey);
|
|
16775
17036
|
} catch (error) {
|
|
16776
17037
|
throw new SessionError(
|
|
16777
17038
|
"Failed to clear sessions",
|
|
@@ -16783,9 +17044,9 @@ var LocalStorageSessionStorage = class {
|
|
|
16783
17044
|
/**
|
|
16784
17045
|
* Check if any session exists
|
|
16785
17046
|
*/
|
|
16786
|
-
async exists() {
|
|
17047
|
+
async exists(keyHash) {
|
|
16787
17048
|
try {
|
|
16788
|
-
return
|
|
17049
|
+
return await this.load(keyHash) !== null;
|
|
16789
17050
|
} catch {
|
|
16790
17051
|
return false;
|
|
16791
17052
|
}
|
|
@@ -16850,6 +17111,14 @@ var SessionManager = class {
|
|
|
16850
17111
|
refreshTimer = null;
|
|
16851
17112
|
eventCallbacks = [];
|
|
16852
17113
|
debug;
|
|
17114
|
+
resolveConfig(configOverride) {
|
|
17115
|
+
const resolvedConfig = {
|
|
17116
|
+
...this.config,
|
|
17117
|
+
...configOverride
|
|
17118
|
+
};
|
|
17119
|
+
validateSessionConfig(resolvedConfig);
|
|
17120
|
+
return resolvedConfig;
|
|
17121
|
+
}
|
|
16853
17122
|
// ========================================================================
|
|
16854
17123
|
// Session Lifecycle
|
|
16855
17124
|
// ========================================================================
|
|
@@ -16866,15 +17135,16 @@ var SessionManager = class {
|
|
|
16866
17135
|
* @returns Created session key
|
|
16867
17136
|
* @throws SessionError if registration fails
|
|
16868
17137
|
*/
|
|
16869
|
-
async createSession() {
|
|
17138
|
+
async createSession(configOverride) {
|
|
16870
17139
|
try {
|
|
16871
17140
|
this.log("Creating new session...");
|
|
17141
|
+
const sessionConfig = this.resolveConfig(configOverride);
|
|
16872
17142
|
const keyPair = generateSecp256k1KeyPair();
|
|
16873
17143
|
const keyHash = computeSessionKeyHash(keyPair.publicKey);
|
|
16874
17144
|
this.log("Generated session key:", keyHash);
|
|
16875
17145
|
const challenge = import_ethers21.ethers.solidityPacked(
|
|
16876
17146
|
["string", "bytes32", "uint256", "uint256"],
|
|
16877
|
-
["registerSession", keyHash,
|
|
17147
|
+
["registerSession", keyHash, sessionConfig.duration, sessionConfig.maxValue]
|
|
16878
17148
|
);
|
|
16879
17149
|
this.log("Challenge prepared, requesting Passkey signature...");
|
|
16880
17150
|
const signature = await this.passkeySign(import_ethers21.ethers.getBytes(challenge));
|
|
@@ -16884,20 +17154,20 @@ var SessionManager = class {
|
|
|
16884
17154
|
publicKeyX: this.credential.publicKeyX,
|
|
16885
17155
|
publicKeyY: this.credential.publicKeyY,
|
|
16886
17156
|
sessionKeyHash: keyHash,
|
|
16887
|
-
duration:
|
|
16888
|
-
maxValue:
|
|
17157
|
+
duration: sessionConfig.duration,
|
|
17158
|
+
maxValue: sessionConfig.maxValue,
|
|
16889
17159
|
requireUV: true
|
|
16890
17160
|
};
|
|
16891
17161
|
await this.hubClient.registerSession(registerParams);
|
|
16892
17162
|
this.log("Session registered on Hub");
|
|
16893
|
-
const expiry = Date.now() +
|
|
17163
|
+
const expiry = Date.now() + sessionConfig.duration * 1e3;
|
|
16894
17164
|
this.currentSession = {
|
|
16895
17165
|
publicKey: keyPair.publicKey,
|
|
16896
17166
|
privateKey: keyPair.privateKey,
|
|
16897
17167
|
keyHash,
|
|
16898
17168
|
expiry,
|
|
16899
|
-
maxValue:
|
|
16900
|
-
chainScopes:
|
|
17169
|
+
maxValue: sessionConfig.maxValue,
|
|
17170
|
+
chainScopes: sessionConfig.chainScopes,
|
|
16901
17171
|
userKeyHash: this.credential.keyHash
|
|
16902
17172
|
};
|
|
16903
17173
|
await this.storage.save(this.currentSession);
|
|
@@ -16922,12 +17192,15 @@ var SessionManager = class {
|
|
|
16922
17192
|
*
|
|
16923
17193
|
* @returns Loaded session or null if no valid session exists
|
|
16924
17194
|
*/
|
|
16925
|
-
async loadSession() {
|
|
17195
|
+
async loadSession(keyHash) {
|
|
16926
17196
|
try {
|
|
16927
|
-
this.log("Loading session from storage...");
|
|
16928
|
-
const session = await this.storage.load();
|
|
17197
|
+
this.log("Loading session from storage...", keyHash ?? "latest");
|
|
17198
|
+
const session = await this.storage.load(keyHash);
|
|
16929
17199
|
if (!session) {
|
|
16930
17200
|
this.log("No session found in storage");
|
|
17201
|
+
if (!keyHash) {
|
|
17202
|
+
this.currentSession = null;
|
|
17203
|
+
}
|
|
16931
17204
|
return null;
|
|
16932
17205
|
}
|
|
16933
17206
|
if (session.expiry <= Date.now()) {
|
|
@@ -16944,27 +17217,43 @@ var SessionManager = class {
|
|
|
16944
17217
|
return session;
|
|
16945
17218
|
} catch (error) {
|
|
16946
17219
|
this.log("Failed to load session:", error);
|
|
16947
|
-
|
|
17220
|
+
if (!keyHash) {
|
|
17221
|
+
await this.storage.clear();
|
|
17222
|
+
}
|
|
16948
17223
|
return null;
|
|
16949
17224
|
}
|
|
16950
17225
|
}
|
|
17226
|
+
async listSessions() {
|
|
17227
|
+
return this.storage.loadAll();
|
|
17228
|
+
}
|
|
17229
|
+
async selectSession(keyHash) {
|
|
17230
|
+
const session = await this.loadSession(keyHash);
|
|
17231
|
+
if (!session) {
|
|
17232
|
+
throw new SessionError(
|
|
17233
|
+
`Session ${keyHash} not found`,
|
|
17234
|
+
"SESSION_NOT_FOUND" /* SESSION_NOT_FOUND */
|
|
17235
|
+
);
|
|
17236
|
+
}
|
|
17237
|
+
return session;
|
|
17238
|
+
}
|
|
16951
17239
|
/**
|
|
16952
17240
|
* Revoke the current session (requires biometric authentication)
|
|
16953
17241
|
*
|
|
16954
17242
|
* @throws SessionError if no active session or revocation fails
|
|
16955
17243
|
*/
|
|
16956
|
-
async revokeSession() {
|
|
16957
|
-
|
|
17244
|
+
async revokeSession(keyHash) {
|
|
17245
|
+
const targetSession = keyHash ? await this.storage.load(keyHash) : this.currentSession;
|
|
17246
|
+
if (!targetSession) {
|
|
16958
17247
|
throw new SessionError(
|
|
16959
|
-
"No active session to revoke",
|
|
16960
|
-
"NO_ACTIVE_SESSION" /* NO_ACTIVE_SESSION */
|
|
17248
|
+
keyHash ? `Session ${keyHash} not found` : "No active session to revoke",
|
|
17249
|
+
keyHash ? "SESSION_NOT_FOUND" /* SESSION_NOT_FOUND */ : "NO_ACTIVE_SESSION" /* NO_ACTIVE_SESSION */
|
|
16961
17250
|
);
|
|
16962
17251
|
}
|
|
16963
17252
|
try {
|
|
16964
|
-
this.log("Revoking session:",
|
|
17253
|
+
this.log("Revoking session:", targetSession.keyHash);
|
|
16965
17254
|
const challenge = import_ethers21.ethers.solidityPacked(
|
|
16966
17255
|
["string", "bytes32"],
|
|
16967
|
-
["revokeSession",
|
|
17256
|
+
["revokeSession", targetSession.keyHash]
|
|
16968
17257
|
);
|
|
16969
17258
|
const signature = await this.passkeySign(import_ethers21.ethers.getBytes(challenge));
|
|
16970
17259
|
this.log("Passkey signature obtained, revoking on Hub...");
|
|
@@ -16972,18 +17261,24 @@ var SessionManager = class {
|
|
|
16972
17261
|
signature,
|
|
16973
17262
|
publicKeyX: this.credential.publicKeyX,
|
|
16974
17263
|
publicKeyY: this.credential.publicKeyY,
|
|
16975
|
-
sessionKeyHash:
|
|
17264
|
+
sessionKeyHash: targetSession.keyHash,
|
|
16976
17265
|
requireUV: true
|
|
16977
17266
|
};
|
|
16978
17267
|
await this.hubClient.revokeSession(revokeParams);
|
|
16979
17268
|
this.log("Session revoked on Hub");
|
|
16980
|
-
await this.storage.
|
|
16981
|
-
|
|
16982
|
-
|
|
16983
|
-
|
|
17269
|
+
await this.storage.remove(targetSession.keyHash);
|
|
17270
|
+
const revokedKeyHash = targetSession.keyHash;
|
|
17271
|
+
const revokedCurrentSession = this.currentSession?.keyHash === revokedKeyHash;
|
|
17272
|
+
if (revokedCurrentSession) {
|
|
17273
|
+
if (this.refreshTimer) {
|
|
17274
|
+
clearTimeout(this.refreshTimer);
|
|
17275
|
+
this.refreshTimer = null;
|
|
17276
|
+
}
|
|
17277
|
+
this.currentSession = await this.storage.load();
|
|
17278
|
+
if (this.currentSession && this.config.autoRefresh) {
|
|
17279
|
+
this.scheduleRefresh();
|
|
17280
|
+
}
|
|
16984
17281
|
}
|
|
16985
|
-
const revokedKeyHash = this.currentSession.keyHash;
|
|
16986
|
-
this.currentSession = null;
|
|
16987
17282
|
this.emit({ type: "session-revoked", keyHash: revokedKeyHash });
|
|
16988
17283
|
this.log("Session revoked successfully");
|
|
16989
17284
|
} catch (error) {
|
|
@@ -17061,45 +17356,46 @@ var SessionManager = class {
|
|
|
17061
17356
|
* @returns Session signature
|
|
17062
17357
|
* @throws SessionError if no active session, expired, or value exceeds limit
|
|
17063
17358
|
*/
|
|
17064
|
-
async signWithSession(action) {
|
|
17065
|
-
|
|
17359
|
+
async signWithSession(action, keyHash) {
|
|
17360
|
+
const session = keyHash ? await this.storage.load(keyHash) : this.currentSession;
|
|
17361
|
+
if (!session) {
|
|
17066
17362
|
throw new SessionError(
|
|
17067
|
-
"No active session available",
|
|
17068
|
-
"NO_ACTIVE_SESSION" /* NO_ACTIVE_SESSION */
|
|
17363
|
+
keyHash ? `Session ${keyHash} not found` : "No active session available",
|
|
17364
|
+
keyHash ? "SESSION_NOT_FOUND" /* SESSION_NOT_FOUND */ : "NO_ACTIVE_SESSION" /* NO_ACTIVE_SESSION */
|
|
17069
17365
|
);
|
|
17070
17366
|
}
|
|
17071
17367
|
const now = Date.now();
|
|
17072
|
-
if (now >=
|
|
17073
|
-
this.emit({ type: "session-expired", keyHash:
|
|
17368
|
+
if (now >= session.expiry) {
|
|
17369
|
+
this.emit({ type: "session-expired", keyHash: session.keyHash });
|
|
17074
17370
|
throw new SessionError(
|
|
17075
17371
|
"Session has expired",
|
|
17076
17372
|
"SESSION_EXPIRED" /* SESSION_EXPIRED */
|
|
17077
17373
|
);
|
|
17078
17374
|
}
|
|
17079
|
-
if (
|
|
17375
|
+
if (session.maxValue > 0n && action.value > session.maxValue) {
|
|
17080
17376
|
throw new SessionError(
|
|
17081
|
-
`Transaction value (${action.value}) exceeds session limit (${
|
|
17377
|
+
`Transaction value (${action.value}) exceeds session limit (${session.maxValue})`,
|
|
17082
17378
|
"VALUE_EXCEEDS_LIMIT" /* VALUE_EXCEEDS_LIMIT */,
|
|
17083
|
-
{ value: action.value, limit:
|
|
17379
|
+
{ value: action.value, limit: session.maxValue }
|
|
17084
17380
|
);
|
|
17085
17381
|
}
|
|
17086
|
-
if (
|
|
17382
|
+
if (session.chainScopes.length > 0 && !session.chainScopes.includes(action.targetChain)) {
|
|
17087
17383
|
throw new SessionError(
|
|
17088
17384
|
`Chain ${action.targetChain} not in session scope`,
|
|
17089
17385
|
"CHAIN_NOT_ALLOWED" /* CHAIN_NOT_ALLOWED */,
|
|
17090
|
-
{ chain: action.targetChain, allowedChains:
|
|
17386
|
+
{ chain: action.targetChain, allowedChains: session.chainScopes }
|
|
17091
17387
|
);
|
|
17092
17388
|
}
|
|
17093
17389
|
this.log("Signing action with session key...");
|
|
17094
17390
|
const messageHash = hashAction(action);
|
|
17095
17391
|
const { signature } = signWithSessionKey(
|
|
17096
|
-
|
|
17392
|
+
session.privateKey,
|
|
17097
17393
|
messageHash
|
|
17098
17394
|
);
|
|
17099
17395
|
const sessionSignature = {
|
|
17100
17396
|
signature,
|
|
17101
|
-
sessionKeyHash:
|
|
17102
|
-
userKeyHash:
|
|
17397
|
+
sessionKeyHash: session.keyHash,
|
|
17398
|
+
userKeyHash: session.userKeyHash,
|
|
17103
17399
|
timestamp: now,
|
|
17104
17400
|
nonce: action.nonce
|
|
17105
17401
|
};
|
|
@@ -17112,8 +17408,8 @@ var SessionManager = class {
|
|
|
17112
17408
|
* @param action Action parameters
|
|
17113
17409
|
* @returns Session-signed action ready for submission
|
|
17114
17410
|
*/
|
|
17115
|
-
async signAction(action) {
|
|
17116
|
-
const signature = await this.signWithSession(action);
|
|
17411
|
+
async signAction(action, keyHash) {
|
|
17412
|
+
const signature = await this.signWithSession(action, keyHash);
|
|
17117
17413
|
return {
|
|
17118
17414
|
action,
|
|
17119
17415
|
signature,
|
|
@@ -18097,6 +18393,7 @@ var VALIDATION_REGISTRY_ABI = [
|
|
|
18097
18393
|
calculatePercentage,
|
|
18098
18394
|
computeKeyHash,
|
|
18099
18395
|
computeSessionKeyHash,
|
|
18396
|
+
configureDefaultRpcUrls,
|
|
18100
18397
|
createAuditEntry,
|
|
18101
18398
|
createChainClient,
|
|
18102
18399
|
createChainDetector,
|
|
@@ -18166,6 +18463,7 @@ var VALIDATION_REGISTRY_ABI = [
|
|
|
18166
18463
|
getExplorerUrl,
|
|
18167
18464
|
getFeatureFlags,
|
|
18168
18465
|
getHubChains,
|
|
18466
|
+
getRpcUrlOverride,
|
|
18169
18467
|
getSequenceFromTxReceipt,
|
|
18170
18468
|
getStacksContractPrincipal,
|
|
18171
18469
|
getStacksExplorerAddressUrl,
|