@vaultkeepr/smart-account 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -20,12 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- CID_REGISTRY_ABI: () => CID_REGISTRY_ABI,
23
+ KEYED_MIGRATION_ENABLED: () => KEYED_MIGRATION_ENABLED,
24
+ PASSAGE_ENABLED: () => PASSAGE_ENABLED,
25
+ canWritePointer: () => canWritePointer,
24
26
  clearIdentity: () => clearIdentity,
25
27
  clearSmartAccountCache: () => clearSmartAccountCache,
26
28
  computeSmartAccountAddress: () => computeSmartAccountAddress,
29
+ createPassageIO: () => createPassageIO,
27
30
  createVaultSmartAccount: () => createVaultSmartAccount,
28
- flushCidOnChainSync: () => flushCidOnChainSync,
31
+ deriveIdentity: () => deriveIdentity,
29
32
  formatSecretKeyForDisplay: () => formatSecretKeyForDisplay,
30
33
  generateSecretKey: () => generateSecretKey,
31
34
  getCachedSmartAccountAddress: () => getCachedSmartAccountAddress,
@@ -35,24 +38,24 @@ __export(index_exports, {
35
38
  getIdentityOwner: () => getIdentityOwner,
36
39
  getIdentitySmartAccount: () => getIdentitySmartAccount,
37
40
  getIdentitySnapshot: () => getIdentitySnapshot,
38
- getOnChainSyncStatus: () => getOnChainSyncStatus,
39
41
  getOwnerFromPassword: () => getOwnerFromPassword,
40
42
  getPimlicoApiKey: () => getPimlicoApiKey,
41
43
  getTargetChain: () => getTargetChain,
44
+ identityState: () => identityState,
42
45
  initIdentityFromPassword: () => initIdentityFromPassword,
43
46
  initIdentityFromSigner: () => initIdentityFromSigner,
44
- isCidRegistryConfigured: () => isCidRegistryConfigured,
45
47
  isIdentityConnected: () => isIdentityConnected,
46
48
  isSmartAccountConfigured: () => isSmartAccountConfigured,
47
49
  isValidSecretKey: () => isValidSecretKey,
50
+ migrateKeyedPointer: () => migrateKeyedPointer,
48
51
  parseSecretKeyInput: () => parseSecretKeyInput,
49
- publishCidOnChain: () => publishCidOnChain,
50
- readCidOnChain: () => readCidOnChain,
51
- resetOnChainSync: () => resetOnChainSync,
52
- scheduleCidOnChainSync: () => scheduleCidOnChainSync,
52
+ readPassageState: () => readPassageState,
53
+ runPassage: () => runPassage,
54
+ runPassageWith: () => runPassageWith,
53
55
  signMessageWithIdentity: () => signMessageWithIdentity,
54
56
  subscribeIdentity: () => subscribeIdentity,
55
- useIdentity: () => useIdentity
57
+ useIdentity: () => useIdentity,
58
+ verifyAAAuth: () => verifyAAAuth
56
59
  });
57
60
  module.exports = __toCommonJS(index_exports);
58
61
 
@@ -214,248 +217,95 @@ function clearSmartAccountCache() {
214
217
  _cachedKey = null;
215
218
  }
216
219
 
217
- // src/owner.ts
218
- var import_core = require("@vaultkeepr/core");
219
- async function getOwnerFromPassword(password, secretKey) {
220
- return (0, import_core.getHiddenWalletFromPassword)(password, secretKey);
221
- }
222
-
223
- // src/cidRegistry.ts
220
+ // src/deriveIdentity.ts
224
221
  var import_viem2 = require("viem");
225
- var import_logger2 = require("@vaultkeepr/logger");
226
- var CID_REGISTRY_ABI = [
227
- {
228
- name: "setCid",
229
- type: "function",
230
- stateMutability: "nonpayable",
231
- inputs: [{ name: "cid", type: "string" }],
232
- outputs: []
233
- },
234
- {
235
- name: "deleteCid",
236
- type: "function",
237
- stateMutability: "nonpayable",
238
- inputs: [],
239
- outputs: []
240
- },
241
- {
242
- name: "getCid",
243
- type: "function",
244
- stateMutability: "view",
245
- inputs: [{ name: "account", type: "address" }],
246
- outputs: [{ name: "", type: "string" }]
247
- },
248
- {
249
- name: "hasCid",
250
- type: "function",
251
- stateMutability: "view",
252
- inputs: [{ name: "account", type: "address" }],
253
- outputs: [{ name: "", type: "bool" }]
254
- },
255
- {
256
- name: "getUpdatedAt",
257
- type: "function",
258
- stateMutability: "view",
259
- inputs: [{ name: "account", type: "address" }],
260
- outputs: [{ name: "", type: "uint256" }]
261
- },
262
- {
263
- name: "nextAllowedUpdate",
264
- type: "function",
265
- stateMutability: "view",
266
- inputs: [{ name: "account", type: "address" }],
267
- outputs: [{ name: "", type: "uint256" }]
268
- },
269
- {
270
- name: "cooldownSeconds",
271
- type: "function",
272
- stateMutability: "view",
273
- inputs: [],
274
- outputs: [{ name: "", type: "uint256" }]
275
- }
276
- ];
277
- function getCidRegistryAddress() {
278
- let addr = "";
279
- try {
280
- addr = process.env.CID_REGISTRY_ADDRESS || "";
281
- } catch {
282
- }
283
- if (addr) return addr;
284
- try {
285
- addr = process.env.NEXT_PUBLIC_CID_REGISTRY_ADDRESS || "";
286
- } catch {
287
- }
288
- if (addr) return addr;
289
- try {
290
- addr = process.env.EXPO_PUBLIC_CID_REGISTRY_ADDRESS || "";
291
- } catch {
292
- }
293
- if (addr) return addr;
294
- return "0x0000000000000000000000000000000000000000";
222
+ async function deriveIdentity(ownerAccount, mode) {
223
+ const aaAddress = await computeSmartAccountAddress(ownerAccount);
224
+ return {
225
+ ownerAddress: ownerAccount.address,
226
+ aaAddress,
227
+ mode
228
+ };
295
229
  }
296
- function isCidRegistryConfigured() {
297
- return getCidRegistryAddress() !== "0x0000000000000000000000000000000000000000" && isSmartAccountConfigured();
230
+ var MAX_SKEW_MS = 5 * 6e4;
231
+ var UNSIGNABLE_OWNER = "verifyAAAuth: owner stub cannot sign";
232
+ function addressOnlyAccount(address) {
233
+ return {
234
+ address,
235
+ type: "local",
236
+ publicKey: "0x",
237
+ source: "custom",
238
+ signMessage: async () => {
239
+ throw new Error(UNSIGNABLE_OWNER);
240
+ },
241
+ signTypedData: async () => {
242
+ throw new Error(UNSIGNABLE_OWNER);
243
+ },
244
+ signTransaction: async () => {
245
+ throw new Error(UNSIGNABLE_OWNER);
246
+ }
247
+ };
298
248
  }
299
- async function publishCidOnChain(smartAccount, cid) {
300
- if (!isCidRegistryConfigured()) {
301
- import_logger2.logger.warn(
302
- "[CidRegistry] Non configur\xE9, skip on-chain publish"
303
- );
304
- return null;
305
- }
249
+ async function verifyAAAuth(params) {
250
+ const rejected = {
251
+ ok: false,
252
+ ownerAddress: import_viem2.zeroAddress,
253
+ aaAddress: import_viem2.zeroAddress
254
+ };
306
255
  try {
307
- const calldata = (0, import_viem2.encodeFunctionData)({
308
- abi: CID_REGISTRY_ABI,
309
- functionName: "setCid",
310
- args: [cid]
311
- });
312
- const userOpHash = await smartAccount.client.sendUserOperation({
313
- calls: [
314
- {
315
- to: getCidRegistryAddress(),
316
- data: calldata,
317
- value: BigInt(0)
318
- }
319
- ]
320
- });
321
- import_logger2.logger.debug(
322
- `[CidRegistry] UserOp soumise: ${userOpHash}`
323
- );
324
- const receipt = await smartAccount.client.waitForUserOperationReceipt({
325
- hash: userOpHash
326
- });
327
- import_logger2.logger.debug(
328
- `[CidRegistry] CID publi\xE9 on-chain \u2014 tx: ${receipt.receipt.transactionHash} | CID: ${cid.slice(0, 20)}...`
256
+ if (!Number.isFinite(params.timestamp) || Math.abs(Date.now() - params.timestamp) > MAX_SKEW_MS) {
257
+ return rejected;
258
+ }
259
+ const signature = params.signature;
260
+ let ownerAddress;
261
+ if (params.claimedOwner) {
262
+ ownerAddress = (0, import_viem2.getAddress)(params.claimedOwner);
263
+ const publicClient = (0, import_viem2.createPublicClient)({
264
+ chain: TARGET_CHAIN,
265
+ transport: (0, import_viem2.http)()
266
+ });
267
+ const valid = await publicClient.verifyMessage({
268
+ address: ownerAddress,
269
+ message: params.message,
270
+ signature
271
+ });
272
+ if (!valid) {
273
+ return {
274
+ ok: false,
275
+ ownerAddress,
276
+ aaAddress: params.claimedAA ? (0, import_viem2.getAddress)(params.claimedAA) : import_viem2.zeroAddress
277
+ };
278
+ }
279
+ } else {
280
+ ownerAddress = await (0, import_viem2.recoverMessageAddress)({
281
+ message: params.message,
282
+ signature
283
+ });
284
+ }
285
+ const claimedAA = params.claimedAA ? (0, import_viem2.getAddress)(params.claimedAA) : null;
286
+ const aaAddress = await computeSmartAccountAddress(
287
+ addressOnlyAccount(ownerAddress)
329
288
  );
330
- return receipt.receipt.transactionHash;
331
- } catch (error) {
332
- import_logger2.logger.error("[CidRegistry] Erreur:", error instanceof Error ? error.message : error);
333
- return null;
334
- }
335
- }
336
- async function readCidOnChain(smartAccountAddress) {
337
- if (!isCidRegistryConfigured()) return null;
338
- try {
339
- const publicClient = (0, import_viem2.createPublicClient)({
340
- chain: TARGET_CHAIN,
341
- transport: (0, import_viem2.http)()
342
- });
343
- const cid = await publicClient.readContract({
344
- address: getCidRegistryAddress(),
345
- abi: CID_REGISTRY_ABI,
346
- functionName: "getCid",
347
- args: [smartAccountAddress]
348
- });
349
- return cid && cid.length > 0 ? cid : null;
350
- } catch (error) {
351
- import_logger2.logger.error("[CidRegistry] Erreur lecture:", error instanceof Error ? error.message : error);
352
- return null;
289
+ if (claimedAA && !(0, import_viem2.isAddressEqual)(claimedAA, aaAddress)) {
290
+ return { ok: false, ownerAddress, aaAddress };
291
+ }
292
+ return { ok: true, ownerAddress, aaAddress };
293
+ } catch {
294
+ return rejected;
353
295
  }
354
296
  }
355
297
 
356
- // src/onChainSync.ts
357
- var import_logger3 = require("@vaultkeepr/logger");
358
- var DEFAULT_DEBOUNCE_MS = 5 * 60 * 1e3;
359
- var _pendingCid = null;
360
- var _pendingSmartAccount = null;
361
- var _debounceTimer = null;
362
- var _lastPublishedCid = null;
363
- var _lastPublishTime = 0;
364
- var _isPublishing = false;
365
- function scheduleCidOnChainSync(smartAccount, cid, debounceMs = DEFAULT_DEBOUNCE_MS) {
366
- if (!isCidRegistryConfigured()) return;
367
- if (cid === _lastPublishedCid) {
368
- import_logger3.logger.debug("[OnChainSync] CID identique, skip");
369
- return;
370
- }
371
- const sa = smartAccount ?? _pendingSmartAccount;
372
- if (!sa) {
373
- import_logger3.logger.warn("[OnChainSync] Pas de Smart Account disponible, skip");
374
- return;
375
- }
376
- _pendingCid = cid;
377
- _pendingSmartAccount = sa;
378
- if (_debounceTimer) {
379
- clearTimeout(_debounceTimer);
380
- }
381
- _debounceTimer = setTimeout(() => {
382
- _executeSync();
383
- }, debounceMs);
384
- import_logger3.logger.debug(
385
- `[OnChainSync] CID planifi\xE9 dans ${(debounceMs / 1e3).toFixed(0)}s : ${cid.slice(0, 20)}...`
386
- );
387
- }
388
- async function flushCidOnChainSync() {
389
- import_logger3.logger.debug(
390
- "[OnChainSync] flush demand\xE9 \u2014 pending:",
391
- _pendingCid?.slice(0, 20),
392
- "SA:",
393
- !!_pendingSmartAccount
394
- );
395
- if (!_pendingCid || !_pendingSmartAccount) {
396
- import_logger3.logger.debug("[OnChainSync] Rien \xE0 flush");
397
- return true;
398
- }
399
- if (_debounceTimer) {
400
- clearTimeout(_debounceTimer);
401
- _debounceTimer = null;
402
- }
403
- import_logger3.logger.debug("[OnChainSync] Flush imm\xE9diat...");
404
- return _executeSync();
405
- }
406
- function getOnChainSyncStatus() {
407
- return {
408
- hasPending: _pendingCid !== null && _pendingCid !== _lastPublishedCid,
409
- pendingCid: _pendingCid,
410
- lastPublishedCid: _lastPublishedCid,
411
- lastPublishTime: _lastPublishTime,
412
- isPublishing: _isPublishing
413
- };
414
- }
415
- function resetOnChainSync() {
416
- if (_debounceTimer) {
417
- clearTimeout(_debounceTimer);
418
- _debounceTimer = null;
419
- }
420
- _pendingCid = null;
421
- _pendingSmartAccount = null;
422
- _lastPublishedCid = null;
423
- _lastPublishTime = 0;
424
- _isPublishing = false;
425
- }
426
- async function _executeSync() {
427
- if (!_pendingCid || !_pendingSmartAccount || _isPublishing) return false;
428
- if (_pendingCid === _lastPublishedCid) {
429
- _pendingCid = null;
430
- return true;
431
- }
432
- _isPublishing = true;
433
- const cid = _pendingCid;
434
- const sa = _pendingSmartAccount;
435
- try {
436
- import_logger3.logger.debug(`[OnChainSync] Publication on-chain: ${cid.slice(0, 20)}...`);
437
- const txHash = await publishCidOnChain(sa, cid);
438
- if (txHash) {
439
- _lastPublishedCid = cid;
440
- _lastPublishTime = Date.now();
441
- _pendingCid = null;
442
- import_logger3.logger.debug(
443
- `[OnChainSync] \u2705 CID publi\xE9 on-chain : ${cid.slice(0, 20)}...`
444
- );
445
- return true;
446
- }
447
- import_logger3.logger.warn("[OnChainSync] Publication \xE9chou\xE9e (null txHash)");
448
- return false;
449
- } catch (error) {
450
- import_logger3.logger.error("[OnChainSync] Erreur publication:", error instanceof Error ? error.message : error);
451
- return false;
452
- } finally {
453
- _isPublishing = false;
298
+ // src/owner.ts
299
+ var import_core = require("@vaultkeepr/core");
300
+ async function getOwnerFromPassword(password, secretKey) {
301
+ if (secretKey) {
302
+ return (0, import_core.getHiddenWalletFromSecretKey)(secretKey);
454
303
  }
304
+ return (0, import_core.getHiddenWalletFromPassword)(password);
455
305
  }
456
306
 
457
307
  // src/identity.ts
458
- var import_logger4 = require("@vaultkeepr/logger");
308
+ var import_logger2 = require("@vaultkeepr/logger");
459
309
  var _state = {
460
310
  owner: null,
461
311
  smartAccount: null,
@@ -481,7 +331,15 @@ async function initIdentityFromPassword(password, secretKey) {
481
331
  mode: "password"
482
332
  });
483
333
  } catch (e) {
484
- import_logger4.logger.warn("[Identity] SA init failed (non-blocking):", e.message);
334
+ import_logger2.logger.warn("[Identity] SA init failed (non-blocking):", e.message);
335
+ }
336
+ }
337
+ let aaAddress = sa?.address ?? null;
338
+ if (!aaAddress && isSmartAccountConfigured()) {
339
+ try {
340
+ aaAddress = await computeSmartAccountAddress(owner);
341
+ } catch (e) {
342
+ import_logger2.logger.warn("[Identity] AA derivation failed (non-blocking):", e.message);
485
343
  }
486
344
  }
487
345
  _state = {
@@ -491,12 +349,13 @@ async function initIdentityFromPassword(password, secretKey) {
491
349
  initialized: true
492
350
  };
493
351
  _notify();
494
- import_logger4.logger.debug(
495
- `[Identity] Connect\xE9 (password) \u2014 adresse: ${(0, import_logger4.redactAddress)(owner.address)}` + (sa ? ` | SA: ${(0, import_logger4.redactAddress)(sa.address)}` : "") + (secretKey ? ` | SK: \u2713` : " | no secretKey")
352
+ import_logger2.logger.debug(
353
+ `[Identity] Connect\xE9 (password) \u2014 adresse: ${(0, import_logger2.redactAddress)(owner.address)}` + (sa ? ` | SA: ${(0, import_logger2.redactAddress)(sa.address)}` : "") + (secretKey ? ` | SK: \u2713` : " | no secretKey")
496
354
  );
497
355
  return {
498
356
  address: owner.address,
499
- smartAccountAddress: sa?.address ?? null
357
+ smartAccountAddress: sa?.address ?? null,
358
+ aaAddress
500
359
  };
501
360
  }
502
361
  async function initIdentityFromSigner(signer, mode = "passkey") {
@@ -505,7 +364,15 @@ async function initIdentityFromSigner(signer, mode = "passkey") {
505
364
  try {
506
365
  sa = await createVaultSmartAccount({ ownerAccount: signer, mode });
507
366
  } catch (e) {
508
- import_logger4.logger.warn("[Identity] SA init failed (non-blocking):", e.message);
367
+ import_logger2.logger.warn("[Identity] SA init failed (non-blocking):", e.message);
368
+ }
369
+ }
370
+ let aaAddress = sa?.address ?? null;
371
+ if (!aaAddress && isSmartAccountConfigured()) {
372
+ try {
373
+ aaAddress = await computeSmartAccountAddress(signer);
374
+ } catch (e) {
375
+ import_logger2.logger.warn("[Identity] AA derivation failed (non-blocking):", e.message);
509
376
  }
510
377
  }
511
378
  _state = {
@@ -515,12 +382,13 @@ async function initIdentityFromSigner(signer, mode = "passkey") {
515
382
  initialized: true
516
383
  };
517
384
  _notify();
518
- import_logger4.logger.info(
385
+ import_logger2.logger.info(
519
386
  `[Identity] Connected (${mode}) \u2014 address: ${signer.address}` + (sa ? ` | SA: ${sa.address}` : "")
520
387
  );
521
388
  return {
522
389
  address: signer.address,
523
- smartAccountAddress: sa?.address ?? null
390
+ smartAccountAddress: sa?.address ?? null,
391
+ aaAddress
524
392
  };
525
393
  }
526
394
  function clearIdentity() {
@@ -532,7 +400,7 @@ function clearIdentity() {
532
400
  };
533
401
  clearSmartAccountCache();
534
402
  _notify();
535
- import_logger4.logger.info("[Identity] Disconnected");
403
+ import_logger2.logger.info("[Identity] Disconnected");
536
404
  }
537
405
  function getIdentityAddress() {
538
406
  return _state.owner?.address ?? null;
@@ -591,24 +459,10 @@ function useIdentity() {
591
459
  const disconnect = (0, import_react.useCallback)(() => {
592
460
  clearIdentity();
593
461
  }, []);
594
- const notifyOnChainSync = (0, import_react.useCallback)(
595
- (cid) => {
596
- const sa = getIdentitySmartAccount();
597
- if (!sa) return;
598
- scheduleCidOnChainSync(sa, cid);
599
- },
600
- []
601
- );
602
- const cleanupOnLock = (0, import_react.useCallback)(async () => {
603
- await flushCidOnChainSync().catch(() => {
604
- });
462
+ const cleanupOnLock = (0, import_react.useCallback)(() => {
605
463
  clearSmartAccountCache();
606
- resetOnChainSync();
607
464
  clearIdentity();
608
- }, []);
609
- const flushOnChainSync = (0, import_react.useCallback)(async () => {
610
- await flushCidOnChainSync().catch(() => {
611
- });
465
+ return Promise.resolve();
612
466
  }, []);
613
467
  return {
614
468
  address: state.owner?.address ?? null,
@@ -617,9 +471,7 @@ function useIdentity() {
617
471
  smartAccountAddress: state.smartAccount?.address ?? null,
618
472
  signMessage,
619
473
  disconnect,
620
- notifyOnChainSync,
621
- cleanupOnLock,
622
- flushOnChainSync
474
+ cleanupOnLock
623
475
  };
624
476
  }
625
477
 
@@ -627,13 +479,12 @@ function useIdentity() {
627
479
  var import_viem3 = require("viem");
628
480
  function generateSecretKey() {
629
481
  const bytes = new Uint8Array(32);
630
- if (typeof globalThis.crypto?.getRandomValues === "function") {
631
- globalThis.crypto.getRandomValues(bytes);
632
- } else {
633
- for (let i = 0; i < 32; i++) {
634
- bytes[i] = Math.floor(Math.random() * 256);
635
- }
482
+ if (typeof globalThis.crypto?.getRandomValues !== "function") {
483
+ throw new Error(
484
+ "[SmartAccount] CSPRNG indisponible: crypto.getRandomValues est requis pour generer une cle secrete. Un fallback Math.random produirait une cle devinable (CWE-338), refuse."
485
+ );
636
486
  }
487
+ globalThis.crypto.getRandomValues(bytes);
637
488
  return (0, import_viem3.bytesToHex)(bytes).slice(2);
638
489
  }
639
490
  function isValidSecretKey(key) {
@@ -646,14 +497,215 @@ function formatSecretKeyForDisplay(key) {
646
497
  function parseSecretKeyInput(input) {
647
498
  return input.replace(/[-\s]/g, "").toLowerCase();
648
499
  }
500
+
501
+ // src/keyPassage.ts
502
+ function identityState(input) {
503
+ if (input.hasSecretKey) return { kind: "ready" };
504
+ if (input.pointer === "moved") return { kind: "pair_required" };
505
+ if (input.pointer === "active") return { kind: "pass_to_key" };
506
+ return { kind: "join_or_create" };
507
+ }
508
+ function canWritePointer(state) {
509
+ return state.kind === "ready" || state.kind === "pass_to_key";
510
+ }
511
+ function sameAddress(a, b) {
512
+ return a.trim().toLowerCase() === b.trim().toLowerCase();
513
+ }
514
+ async function runPassage(io, opts) {
515
+ if (opts.hasSecretKey) return { status: "already_keyed" };
516
+ const legacy = await io.readLegacyPointer();
517
+ if (legacy.moved) {
518
+ const pending = await io.peekPendingKey();
519
+ if (pending && legacy.movedTo && sameAddress(await io.smartAccountOf(pending), legacy.movedTo)) {
520
+ await io.activatePendingKey();
521
+ return { status: "moved", smartAccount: legacy.movedTo };
522
+ }
523
+ if (pending) await io.discardPendingKey();
524
+ return { status: "already_moved" };
525
+ }
526
+ if (!legacy.cid) return { status: "nothing_to_pass" };
527
+ const secretKey = await io.getOrCreatePendingKey();
528
+ const smartAccount = await io.smartAccountOf(secretKey);
529
+ await io.writeSmartAccountPointer(smartAccount, legacy.cid);
530
+ await io.markLegacyMoved(smartAccount);
531
+ await io.activatePendingKey();
532
+ return { status: "moved", smartAccount };
533
+ }
534
+
535
+ // src/passageClient.ts
536
+ var PASSAGE_ENABLED = false;
537
+ var DELEGATION_TTL_SECONDS = 300;
538
+ async function postJson(env, path, body) {
539
+ const res = await env.fetch(`${env.apiBase}${path}`, {
540
+ method: "POST",
541
+ headers: { "Content-Type": "application/json" },
542
+ body: JSON.stringify(body)
543
+ });
544
+ if (!res.ok) throw new Error(`passage ${path} failed (${res.status})`);
545
+ return res.json();
546
+ }
547
+ function createPassageIO(env) {
548
+ const legacyAddress = env.legacyAddress.toLowerCase();
549
+ const delegation2 = async (sign) => {
550
+ const sessionId = env.newSessionId();
551
+ const expiryTimestamp = Math.floor(env.now() / 1e3) + DELEGATION_TTL_SECONDS;
552
+ const delegationSignature = await sign(env.formatDelegation(sessionId, expiryTimestamp));
553
+ return { sessionId, expiryTimestamp, delegationSignature };
554
+ };
555
+ return {
556
+ async readLegacyPointer() {
557
+ const d = await delegation2((m) => env.signLegacy(m));
558
+ const query = [
559
+ `wallet=${encodeURIComponent(legacyAddress)}`,
560
+ `delegationSignature=${encodeURIComponent(d.delegationSignature)}`,
561
+ `sessionId=${encodeURIComponent(d.sessionId)}`,
562
+ `expiryTimestamp=${d.expiryTimestamp}`
563
+ ].join("&");
564
+ const res = await env.fetch(`${env.apiBase}/api/vault-cid?${query}`);
565
+ if (!res.ok) throw new Error(`passage read failed (${res.status})`);
566
+ const json = await res.json();
567
+ return { cid: json.cid ?? null, moved: !!json.moved, movedTo: json.movedTo ?? void 0 };
568
+ },
569
+ peekPendingKey: () => env.pending.read(),
570
+ async getOrCreatePendingKey() {
571
+ const existing = await env.pending.read();
572
+ if (existing) return existing;
573
+ const secretKey = env.newSecretKey();
574
+ await env.pending.write(secretKey);
575
+ return secretKey;
576
+ },
577
+ smartAccountOf: (secretKey) => env.smartAccountOf(secretKey),
578
+ async writeSmartAccountPointer(smartAccount, cid) {
579
+ const pendingKey = await env.pending.read();
580
+ if (!pendingKey) throw new Error("passage: no pending key");
581
+ const d = await delegation2((m) => env.signWithKey(pendingKey, m));
582
+ await postJson(env, "/api/vault-cid", {
583
+ walletAddress: smartAccount,
584
+ cid,
585
+ delegationSignature: d.delegationSignature,
586
+ sessionId: d.sessionId,
587
+ expiryTimestamp: d.expiryTimestamp
588
+ });
589
+ },
590
+ async markLegacyMoved(smartAccount) {
591
+ const d = await delegation2((m) => env.signLegacy(m));
592
+ await postJson(env, "/api/vault-cid/move", {
593
+ walletAddress: legacyAddress,
594
+ targetSmartAccount: smartAccount,
595
+ delegationSignature: d.delegationSignature,
596
+ sessionId: d.sessionId,
597
+ expiryTimestamp: d.expiryTimestamp
598
+ });
599
+ },
600
+ async activatePendingKey() {
601
+ const pendingKey = await env.pending.read();
602
+ if (!pendingKey) throw new Error("passage: no pending key");
603
+ await env.activate(pendingKey);
604
+ await env.pending.clear();
605
+ },
606
+ discardPendingKey: () => env.pending.clear()
607
+ };
608
+ }
609
+ async function readPassageState(env, hasSecretKey) {
610
+ const legacy = await createPassageIO(env).readLegacyPointer();
611
+ const pointer = legacy.moved ? "moved" : legacy.cid ? "active" : "none";
612
+ return identityState({ hasSecretKey, pointer });
613
+ }
614
+ function runPassageWith(env, hasSecretKey) {
615
+ return runPassage(createPassageIO(env), { hasSecretKey });
616
+ }
617
+
618
+ // src/keyedMigration.ts
619
+ var KEYED_MIGRATION_ENABLED = false;
620
+ var DELEGATION_TTL_SECONDS2 = 300;
621
+ async function delegation(env) {
622
+ const sessionId = env.newSessionId();
623
+ const expiryTimestamp = Math.floor(env.now() / 1e3) + DELEGATION_TTL_SECONDS2;
624
+ const delegationSignature = await env.signWithKey(env.formatDelegation(sessionId, expiryTimestamp));
625
+ return { sessionId, expiryTimestamp, delegationSignature };
626
+ }
627
+ async function readPointer(env, wallet) {
628
+ const d = await delegation(env);
629
+ const query = [
630
+ `wallet=${encodeURIComponent(wallet)}`,
631
+ `delegationSignature=${encodeURIComponent(d.delegationSignature)}`,
632
+ `sessionId=${encodeURIComponent(d.sessionId)}`,
633
+ `expiryTimestamp=${d.expiryTimestamp}`
634
+ ].join("&");
635
+ const res = await env.fetch(`${env.apiBase}/api/vault-cid?${query}`);
636
+ if (!res.ok) throw new Error(`keyed migration: read failed (${res.status})`);
637
+ const json = await res.json();
638
+ return { cid: json.cid ?? null, moved: !!json.moved, movedTo: json.movedTo ?? void 0 };
639
+ }
640
+ async function copyPointer(env, smartAccount, cid) {
641
+ const d = await delegation(env);
642
+ const res = await env.fetch(`${env.apiBase}/api/vault-cid`, {
643
+ method: "POST",
644
+ headers: { "Content-Type": "application/json" },
645
+ body: JSON.stringify({
646
+ walletAddress: smartAccount,
647
+ cid,
648
+ delegationSignature: d.delegationSignature,
649
+ sessionId: d.sessionId,
650
+ expiryTimestamp: d.expiryTimestamp
651
+ })
652
+ });
653
+ if (!res.ok) throw new Error(`keyed migration: SA copy failed (${res.status})`);
654
+ }
655
+ async function markMoved(env, owner, smartAccount) {
656
+ const d = await delegation(env);
657
+ const res = await env.fetch(`${env.apiBase}/api/vault-cid/move`, {
658
+ method: "POST",
659
+ headers: { "Content-Type": "application/json" },
660
+ body: JSON.stringify({
661
+ walletAddress: owner,
662
+ targetSmartAccount: smartAccount,
663
+ delegationSignature: d.delegationSignature,
664
+ sessionId: d.sessionId,
665
+ expiryTimestamp: d.expiryTimestamp
666
+ })
667
+ });
668
+ if (!res.ok) throw new Error(`keyed migration: move failed (${res.status})`);
669
+ }
670
+ async function reconcileAfterMove(env, owner, smartAccount) {
671
+ const frozen = await readPointer(env, owner);
672
+ if (!frozen.cid) throw new Error("keyed migration: legacy pointer empty after the move");
673
+ const copied = await readPointer(env, smartAccount);
674
+ if (copied.cid === frozen.cid) return;
675
+ await copyPointer(env, smartAccount, frozen.cid);
676
+ const check = await readPointer(env, smartAccount);
677
+ if (check.cid !== frozen.cid) throw new Error("keyed migration: SA copy differs after the move");
678
+ }
679
+ async function migrateKeyedPointer(env) {
680
+ const owner = env.ownerAddress.toLowerCase();
681
+ const smartAccount = env.smartAccount.toLowerCase();
682
+ const legacy = await readPointer(env, owner);
683
+ if (legacy.moved) {
684
+ if ((legacy.movedTo ?? "").toLowerCase() !== smartAccount) {
685
+ throw new Error("keyed migration: legacy pointer moved to another smart account");
686
+ }
687
+ await reconcileAfterMove(env, owner, smartAccount);
688
+ return "already_moved";
689
+ }
690
+ if (!legacy.cid) return "no_pointer";
691
+ const target = await readPointer(env, smartAccount);
692
+ if (target.cid !== null && target.cid !== legacy.cid) return "conflict";
693
+ if (target.cid === null) await copyPointer(env, smartAccount, legacy.cid);
694
+ await markMoved(env, owner, smartAccount);
695
+ await reconcileAfterMove(env, owner, smartAccount);
696
+ return "moved";
697
+ }
649
698
  // Annotate the CommonJS export names for ESM import in node:
650
699
  0 && (module.exports = {
651
- CID_REGISTRY_ABI,
700
+ KEYED_MIGRATION_ENABLED,
701
+ PASSAGE_ENABLED,
702
+ canWritePointer,
652
703
  clearIdentity,
653
704
  clearSmartAccountCache,
654
705
  computeSmartAccountAddress,
706
+ createPassageIO,
655
707
  createVaultSmartAccount,
656
- flushCidOnChainSync,
708
+ deriveIdentity,
657
709
  formatSecretKeyForDisplay,
658
710
  generateSecretKey,
659
711
  getCachedSmartAccountAddress,
@@ -663,22 +715,22 @@ function parseSecretKeyInput(input) {
663
715
  getIdentityOwner,
664
716
  getIdentitySmartAccount,
665
717
  getIdentitySnapshot,
666
- getOnChainSyncStatus,
667
718
  getOwnerFromPassword,
668
719
  getPimlicoApiKey,
669
720
  getTargetChain,
721
+ identityState,
670
722
  initIdentityFromPassword,
671
723
  initIdentityFromSigner,
672
- isCidRegistryConfigured,
673
724
  isIdentityConnected,
674
725
  isSmartAccountConfigured,
675
726
  isValidSecretKey,
727
+ migrateKeyedPointer,
676
728
  parseSecretKeyInput,
677
- publishCidOnChain,
678
- readCidOnChain,
679
- resetOnChainSync,
680
- scheduleCidOnChainSync,
729
+ readPassageState,
730
+ runPassage,
731
+ runPassageWith,
681
732
  signMessageWithIdentity,
682
733
  subscribeIdentity,
683
- useIdentity
734
+ useIdentity,
735
+ verifyAAAuth
684
736
  });