@tatchi-xyz/sdk 0.17.0 → 0.18.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.
Files changed (122) hide show
  1. package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
  2. package/dist/cjs/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  3. package/dist/cjs/core/EmailRecovery/index.js +32 -20
  4. package/dist/cjs/core/EmailRecovery/index.js.map +1 -1
  5. package/dist/cjs/core/TatchiPasskey/emailRecovery.js +519 -448
  6. package/dist/cjs/core/TatchiPasskey/emailRecovery.js.map +1 -1
  7. package/dist/cjs/core/TatchiPasskey/index.js +1 -0
  8. package/dist/cjs/core/TatchiPasskey/index.js.map +1 -1
  9. package/dist/cjs/core/TatchiPasskey/relay.js +23 -1
  10. package/dist/cjs/core/TatchiPasskey/relay.js.map +1 -1
  11. package/dist/cjs/core/WalletIframe/client/IframeTransport.js +0 -7
  12. package/dist/cjs/core/WalletIframe/client/IframeTransport.js.map +1 -1
  13. package/dist/cjs/core/WalletIframe/client/router.js +6 -2
  14. package/dist/cjs/core/WalletIframe/client/router.js.map +1 -1
  15. package/dist/cjs/core/rpcCalls.js +8 -0
  16. package/dist/cjs/core/rpcCalls.js.map +1 -1
  17. package/dist/cjs/index.js +6 -2
  18. package/dist/cjs/index.js.map +1 -1
  19. package/dist/cjs/react/components/AccountMenuButton/{LinkedDevicesModal-B6api181.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
  20. package/dist/{esm/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map → cjs/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
  21. package/dist/cjs/react/components/AccountMenuButton/{ProfileDropdown-B-DrG_u5.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
  22. package/dist/{esm/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map → cjs/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
  23. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
  24. package/dist/cjs/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
  25. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css → TouchIcon-BQWentvJ.css} +1 -1
  26. package/dist/cjs/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
  27. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css → PasskeyAuthMenu-DwrzWMYx.css} +1 -1
  28. package/dist/cjs/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
  29. package/dist/cjs/react/components/{ShowQRCode-nZhZSaba.css → ShowQRCode-CCN4h6Uv.css} +1 -1
  30. package/dist/cjs/react/components/{ShowQRCode-nZhZSaba.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
  31. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js +27 -32
  32. package/dist/cjs/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  33. package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +69 -0
  34. package/dist/cjs/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  35. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js +32 -20
  36. package/dist/cjs/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  37. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js +519 -448
  38. package/dist/cjs/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  39. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js +1 -0
  40. package/dist/cjs/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  41. package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
  42. package/dist/cjs/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
  43. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js +0 -7
  44. package/dist/cjs/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  45. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js +6 -2
  46. package/dist/cjs/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  47. package/dist/cjs/react/sdk/src/core/rpcCalls.js +8 -0
  48. package/dist/cjs/react/sdk/src/core/rpcCalls.js.map +1 -1
  49. package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
  50. package/dist/esm/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  51. package/dist/esm/core/EmailRecovery/index.js +28 -21
  52. package/dist/esm/core/EmailRecovery/index.js.map +1 -1
  53. package/dist/esm/core/TatchiPasskey/emailRecovery.js +519 -448
  54. package/dist/esm/core/TatchiPasskey/emailRecovery.js.map +1 -1
  55. package/dist/esm/core/TatchiPasskey/index.js +2 -1
  56. package/dist/esm/core/TatchiPasskey/index.js.map +1 -1
  57. package/dist/esm/core/TatchiPasskey/relay.js +23 -1
  58. package/dist/esm/core/TatchiPasskey/relay.js.map +1 -1
  59. package/dist/esm/core/WalletIframe/client/IframeTransport.js +0 -7
  60. package/dist/esm/core/WalletIframe/client/IframeTransport.js.map +1 -1
  61. package/dist/esm/core/WalletIframe/client/router.js +7 -3
  62. package/dist/esm/core/WalletIframe/client/router.js.map +1 -1
  63. package/dist/esm/core/rpcCalls.js +8 -1
  64. package/dist/esm/core/rpcCalls.js.map +1 -1
  65. package/dist/esm/index.js +4 -1
  66. package/dist/esm/index.js.map +1 -1
  67. package/dist/esm/react/components/AccountMenuButton/{LinkedDevicesModal-B6api181.css → LinkedDevicesModal-CSSowiHP.css} +1 -1
  68. package/dist/{cjs/react/components/AccountMenuButton/LinkedDevicesModal-B6api181.css.map → esm/react/components/AccountMenuButton/LinkedDevicesModal-CSSowiHP.css.map} +1 -1
  69. package/dist/esm/react/components/AccountMenuButton/{ProfileDropdown-B-DrG_u5.css → ProfileDropdown-CEPMZ1gY.css} +1 -1
  70. package/dist/{cjs/react/components/AccountMenuButton/ProfileDropdown-B-DrG_u5.css.map → esm/react/components/AccountMenuButton/ProfileDropdown-CEPMZ1gY.css.map} +1 -1
  71. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css → Web3AuthProfileButton-DopOg7Xc.css} +1 -1
  72. package/dist/esm/react/components/AccountMenuButton/{Web3AuthProfileButton-BnZDUeCL.css.map → Web3AuthProfileButton-DopOg7Xc.css.map} +1 -1
  73. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css → TouchIcon-BQWentvJ.css} +1 -1
  74. package/dist/esm/react/components/AccountMenuButton/icons/{TouchIcon-CAGCi8MY.css.map → TouchIcon-BQWentvJ.css.map} +1 -1
  75. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css → PasskeyAuthMenu-DwrzWMYx.css} +1 -1
  76. package/dist/esm/react/components/PasskeyAuthMenu/{PasskeyAuthMenu-CNNxVj4L.css.map → PasskeyAuthMenu-DwrzWMYx.css.map} +1 -1
  77. package/dist/esm/react/components/{ShowQRCode-nZhZSaba.css → ShowQRCode-CCN4h6Uv.css} +1 -1
  78. package/dist/esm/react/components/{ShowQRCode-nZhZSaba.css.map → ShowQRCode-CCN4h6Uv.css.map} +1 -1
  79. package/dist/esm/react/hooks/usePreconnectWalletAssets.js +27 -32
  80. package/dist/esm/react/hooks/usePreconnectWalletAssets.js.map +1 -1
  81. package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js +63 -0
  82. package/dist/esm/react/sdk/src/core/EmailRecovery/emailRecoveryPendingStore.js.map +1 -0
  83. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js +28 -21
  84. package/dist/esm/react/sdk/src/core/EmailRecovery/index.js.map +1 -1
  85. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js +519 -448
  86. package/dist/esm/react/sdk/src/core/TatchiPasskey/emailRecovery.js.map +1 -1
  87. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js +2 -1
  88. package/dist/esm/react/sdk/src/core/TatchiPasskey/index.js.map +1 -1
  89. package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js +23 -1
  90. package/dist/esm/react/sdk/src/core/TatchiPasskey/relay.js.map +1 -1
  91. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js +0 -7
  92. package/dist/esm/react/sdk/src/core/WalletIframe/client/IframeTransport.js.map +1 -1
  93. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js +7 -3
  94. package/dist/esm/react/sdk/src/core/WalletIframe/client/router.js.map +1 -1
  95. package/dist/esm/react/sdk/src/core/rpcCalls.js +8 -1
  96. package/dist/esm/react/sdk/src/core/rpcCalls.js.map +1 -1
  97. package/dist/esm/sdk/offline-export-app.js.map +1 -1
  98. package/dist/esm/sdk/{router-BLFegW7J.js → router-DuGYOd3G.js} +6 -9
  99. package/dist/esm/sdk/{rpcCalls-DEv9x5-f.js → rpcCalls-BQrJMTdg.js} +2 -2
  100. package/dist/esm/sdk/{rpcCalls-OhgEeFig.js → rpcCalls-YVeUVMk2.js} +8 -1
  101. package/dist/esm/sdk/wallet-iframe-host.js +624 -471
  102. package/dist/esm/wasm_vrf_worker/pkg/wasm_vrf_worker_bg.wasm +0 -0
  103. package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts +25 -0
  104. package/dist/types/src/core/EmailRecovery/emailRecoveryPendingStore.d.ts.map +1 -0
  105. package/dist/types/src/core/EmailRecovery/index.d.ts +1 -0
  106. package/dist/types/src/core/EmailRecovery/index.d.ts.map +1 -1
  107. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts +35 -6
  108. package/dist/types/src/core/TatchiPasskey/emailRecovery.d.ts.map +1 -1
  109. package/dist/types/src/core/TatchiPasskey/index.d.ts +2 -2
  110. package/dist/types/src/core/TatchiPasskey/index.d.ts.map +1 -1
  111. package/dist/types/src/core/TatchiPasskey/relay.d.ts +2 -1
  112. package/dist/types/src/core/TatchiPasskey/relay.d.ts.map +1 -1
  113. package/dist/types/src/core/WalletIframe/client/IframeTransport.d.ts.map +1 -1
  114. package/dist/types/src/core/WalletIframe/client/router.d.ts +3 -3
  115. package/dist/types/src/core/WalletIframe/client/router.d.ts.map +1 -1
  116. package/dist/types/src/core/rpcCalls.d.ts +9 -0
  117. package/dist/types/src/core/rpcCalls.d.ts.map +1 -1
  118. package/dist/types/src/index.d.ts +1 -0
  119. package/dist/types/src/index.d.ts.map +1 -1
  120. package/dist/types/src/react/hooks/usePreconnectWalletAssets.d.ts.map +1 -1
  121. package/dist/workers/wasm_vrf_worker_bg.wasm +0 -0
  122. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"rpcCalls.js","names":["error: any","addKeyTxResult: FinalExecutionOutcome","storeDeviceLinkingTxResult: FinalExecutionOutcome","txError: any","err: unknown"],"sources":["../../../../../../src/core/rpcCalls.ts"],"sourcesContent":["/**\n * Consolidated NEAR Contract Calls\n *\n * This file contains all the NEAR contract calls made to the web3authn contract\n * throughout the passkey SDK. It provides a centralized location for all\n * contract interactions and makes it easier to maintain and update contract\n * call patterns.\n */\n\nimport type { FinalExecutionOutcome } from '@near-js/types';\nimport type { NearClient, SignedTransaction } from './NearClient';\nimport type { ContractStoredAuthenticator } from './TatchiPasskey/recoverAccount';\nimport type { PasskeyManagerContext } from './TatchiPasskey';\nimport type { AccountId } from './types/accountIds';\nimport type { DeviceLinkingSSEEvent } from './types/sdkSentEvents';\nimport type {\n StoredAuthenticator,\n WebAuthnRegistrationCredential,\n WebAuthnAuthenticationCredential\n} from './types/webauthn';\n\nimport { ActionPhase, DeviceLinkingPhase, DeviceLinkingStatus } from './types/sdkSentEvents';\nimport { ActionType, type ActionArgs } from './types/actions';\nimport { VRFChallenge } from './types/vrf-worker';\nimport { DEFAULT_WAIT_STATUS, TransactionContext } from './types/rpc';\nimport type { AuthenticatorOptions } from './types/authenticatorOptions';\nimport type { ConfirmationConfig } from './types/signer-worker';\nimport { base64UrlDecode, base64UrlEncode } from '../utils/encoders';\nimport { errorMessage } from '../utils/errors';\nimport type { EmailRecoveryContracts } from './types/tatchi';\nimport { DEFAULT_EMAIL_RECOVERY_CONTRACTS } from './defaultConfigs';\n\n// ===========================\n// CONTRACT CALL RESPONSES\n// ===========================\n\nexport interface DeviceLinkingResult {\n linkedAccountId: string;\n deviceNumber: number;\n}\n\nexport interface CredentialIdsResult {\n credentialIds: string[];\n}\n\nexport interface AuthenticatorsResult {\n authenticators: Array<[string, ContractStoredAuthenticator]>;\n}\n\n// ===========================\n// DEVICE LINKING CONTRACT CALLS\n// ===========================\n\n/**\n * Query the contract to get the account linked to a device public key\n * Used in device linking flow to check if a device key has been added\n *\n * NEAR does not provide a way to lookup the AccountID an access key has access to.\n * So we store a temporary mapping in the contract to lookup pubkey -> account ID.\n */\nexport async function getDeviceLinkingAccountContractCall(\n nearClient: NearClient,\n contractId: string,\n devicePublicKey: string\n): Promise<DeviceLinkingResult | null> {\n try {\n const result = await nearClient.callFunction<\n { device_public_key: string },\n [string, number | string]\n >(\n contractId,\n 'get_device_linking_account',\n { device_public_key: devicePublicKey }\n );\n\n // Handle different result formats\n if (result && Array.isArray(result) && result.length >= 2) {\n const [linkedAccountId, deviceNumberRaw] = result;\n const deviceNumber = Number(deviceNumberRaw);\n if (!Number.isSafeInteger(deviceNumber) || deviceNumber < 0) {\n console.warn(\n 'Invalid deviceNumber returned from get_device_linking_account:',\n deviceNumberRaw\n );\n return null;\n }\n return {\n linkedAccountId,\n deviceNumber\n };\n }\n\n return null;\n } catch (error: any) {\n console.warn('Failed to get device linking account:', error.message);\n return null;\n }\n}\n\n// ===========================\n// DEVICE LINKING TRANSACTION CALLS\n// ===========================\n\n/**\n * Execute device1's linking transactions (AddKey + Contract mapping)\n * This function signs and broadcasts both transactions required for device linking\n */\nexport async function executeDeviceLinkingContractCalls({\n context,\n device1AccountId,\n device2PublicKey,\n nextNonce,\n nextNextNonce,\n nextNextNextNonce,\n txBlockHash,\n vrfChallenge,\n onEvent,\n confirmationConfigOverride,\n confirmerText,\n}: {\n context: PasskeyManagerContext,\n device1AccountId: AccountId,\n device2PublicKey: string,\n nextNonce: string,\n nextNextNonce: string,\n nextNextNextNonce: string,\n txBlockHash: string,\n vrfChallenge: VRFChallenge,\n onEvent?: (event: DeviceLinkingSSEEvent) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n confirmerText?: { title?: string; body?: string };\n}): Promise<{\n addKeyTxResult: FinalExecutionOutcome;\n storeDeviceLinkingTxResult: FinalExecutionOutcome;\n signedDeleteKeyTransaction: SignedTransaction\n}> {\n\n // Sign three transactions with one PRF authentication\n const signedTransactions = await context.webAuthnManager.signTransactionsWithActions({\n rpcCall: {\n contractId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n nearRpcUrl: context.webAuthnManager.tatchiPasskeyConfigs.nearRpcUrl,\n nearAccountId: device1AccountId\n },\n confirmationConfigOverride,\n title: confirmerText?.title,\n body: confirmerText?.body,\n transactions: [\n // Transaction 1: AddKey - Add Device2's key to Device1's account\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.AddKey,\n public_key: device2PublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape, matching near-api-js:\n // { nonce: number, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n }),\n }],\n nonce: nextNonce,\n },\n // Transaction 2: Store temporary mapping in contract so Device2 can lookup Device1's accountID.\n {\n receiverId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n actions: [{\n action_type: ActionType.FunctionCall,\n method_name: 'store_device_linking_mapping',\n args: JSON.stringify({\n device_public_key: device2PublicKey,\n target_account_id: device1AccountId,\n }),\n gas: '30000000000000', // 30 TGas for device linking with yield promise automatic cleanup\n deposit: '0'\n }],\n nonce: nextNextNonce,\n },\n // Transaction 3: Remove Device2's temporary key if it fails to complete linking after a timeout\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.DeleteKey,\n public_key: device2PublicKey\n }],\n nonce: nextNextNextNonce,\n }\n ],\n onEvent: (progress) => {\n // Bridge all action progress events to the parent so the wallet iframe overlay\n // can expand during user confirmation in wallet-iframe mode.\n try { onEvent?.(progress as any); } catch { }\n // Keep existing mapping for device linking semantics; surface signing as a loading state\n if (progress.phase == ActionPhase.STEP_6_TRANSACTION_SIGNING_COMPLETE) {\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: progress.message || 'Transaction signing in progress...'\n })\n }\n }\n });\n\n if (!signedTransactions[0].signedTransaction) {\n throw new Error('AddKey transaction signing failed');\n }\n if (!signedTransactions[1].signedTransaction) {\n throw new Error('Contract mapping transaction signing failed');\n }\n if (!signedTransactions[2].signedTransaction) {\n throw new Error('DeleteKey transaction signing failed');\n }\n\n // Broadcast just the first 2 transactions: addKey and store device linking mapping\n let addKeyTxResult: FinalExecutionOutcome;\n let storeDeviceLinkingTxResult: FinalExecutionOutcome;\n try {\n console.debug('LinkDeviceFlow: AddKey transaction details:', {\n receiverId: signedTransactions[0].signedTransaction.transaction.receiverId,\n actions: signedTransactions[0].signedTransaction.transaction.actions || [],\n transactionKeys: Object.keys(signedTransactions[0].signedTransaction.transaction),\n });\n\n addKeyTxResult = await context.nearClient.sendTransaction(\n signedTransactions[0].signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceAddKey\n );\n console.log('LinkDeviceFlow: AddKey transaction result:', addKeyTxResult?.transaction?.hash);\n\n // Send success events immediately after AddKey succeeds\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `AddKey transaction completed successfully!`\n });\n\n // Check if contract mapping transaction is valid before attempting to broadcast\n const contractTx = signedTransactions[1].signedTransaction;\n console.log('LinkDeviceFlow: Contract mapping transaction details:', {\n receiverId: contractTx.transaction.receiverId,\n actions: (contractTx.transaction.actions || []).length\n });\n\n // Standard timeout since nonce conflict should be resolved by the 2s delay\n storeDeviceLinkingTxResult = await context.nearClient.sendTransaction(\n contractTx,\n DEFAULT_WAIT_STATUS.linkDeviceAccountMapping\n );\n\n } catch (txError: any) {\n console.error('LinkDeviceFlow: Transaction broadcasting failed:', txError);\n throw new Error(`Transaction broadcasting failed: ${txError.message}`);\n }\n\n onEvent?.({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Device linking completed successfully!`\n });\n\n return {\n addKeyTxResult,\n storeDeviceLinkingTxResult,\n signedDeleteKeyTransaction: signedTransactions[2].signedTransaction\n };\n}\n\n// ===========================\n// ACCOUNT RECOVERY CONTRACT CALLS\n// ===========================\n\n/**\n * Get credential IDs associated with an account from the contract\n * Used in account recovery to discover available credentials\n */\nexport async function getCredentialIdsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<string[]> {\n try {\n const credentialIds = await nearClient.callFunction<{ account_id: AccountId }, string[]>(\n contractId,\n 'get_credential_ids_by_account',\n { account_id: accountId }\n );\n return credentialIds || [];\n } catch (error: any) {\n console.warn('Failed to fetch credential IDs from contract:', error.message);\n return [];\n }\n}\n\n/**\n * Get all authenticators stored for a user from the contract\n * Used in account recovery to sync authenticator data\n */\nexport async function getAuthenticatorsByUser(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<[string, ContractStoredAuthenticator][]> {\n try {\n const authenticatorsResult = await nearClient.view<{ user_id: AccountId }, [string, ContractStoredAuthenticator][]>({\n account: contractId,\n method: 'get_authenticators_by_user',\n args: { user_id: accountId }\n });\n\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult;\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\nexport async function syncAuthenticatorsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<Array<{ credentialId: string, authenticator: StoredAuthenticator }>> {\n try {\n const authenticatorsResult = await getAuthenticatorsByUser(nearClient, contractId, accountId);\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult.map(([credentialId, contractAuthenticator]) => {\n console.log(`Contract authenticator device_number for ${credentialId}:`, contractAuthenticator.device_number);\n\n const transports = Array.isArray(contractAuthenticator.transports)\n ? contractAuthenticator.transports\n : [];\n\n const registered = (() => {\n const raw = String((contractAuthenticator as any).registered ?? '');\n if (!raw) return new Date(0);\n if (/^\\d+$/.test(raw)) {\n const ts = Number(raw);\n return Number.isFinite(ts) ? new Date(ts) : new Date(0);\n }\n const d = new Date(raw);\n return Number.isFinite(d.getTime()) ? d : new Date(0);\n })();\n\n const vrfPublicKeys = (() => {\n const raw = (contractAuthenticator as any).vrf_public_keys;\n if (!raw) return undefined;\n if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'string') {\n return raw as string[];\n }\n if (Array.isArray(raw)) {\n return raw\n .map((entry: unknown) => {\n if (!entry) return null;\n if (entry instanceof Uint8Array) return base64UrlEncode(entry);\n if (Array.isArray(entry)) return base64UrlEncode(new Uint8Array(entry));\n return null;\n })\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n }\n return undefined;\n })();\n\n return {\n credentialId,\n authenticator: {\n credentialId,\n credentialPublicKey: new Uint8Array(contractAuthenticator.credential_public_key),\n transports,\n userId: accountId,\n name: `Device ${contractAuthenticator.device_number} Authenticator`,\n registered,\n // Store the actual device number from contract (no fallback)\n deviceNumber: contractAuthenticator.device_number,\n vrfPublicKeys\n }\n };\n });\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\n// ===========================\n// RECOVERY EMAIL CONTRACT CALLS\n// ===========================\n\n/**\n * Fetch on-chain recovery email hashes from the per-account contract.\n * Returns [] when no contract is deployed or on failure.\n */\nexport async function getRecoveryEmailHashesContractCall(\n nearClient: NearClient,\n accountId: AccountId\n): Promise<number[][]> {\n try {\n const code = await nearClient.viewCode(accountId);\n const hasContract = !!code && code.byteLength > 0;\n if (!hasContract) return [];\n\n const hashes = await nearClient.view<Record<string, never>, number[][]>({\n account: accountId,\n method: 'get_recovery_emails',\n args: {} as Record<string, never>,\n });\n\n return Array.isArray(hashes) ? (hashes as number[][]) : [];\n } catch (error) {\n console.error('[rpcCalls] Failed to fetch recovery email hashes', error);\n return [];\n }\n}\n\n/**\n * Build action args to update on-chain recovery emails for an account.\n * If the per-account contract is missing, deploy/attach the global recoverer via `init_email_recovery`.\n */\nexport async function buildSetRecoveryEmailsActions(\n nearClient: NearClient,\n accountId: AccountId,\n recoveryEmailHashes: number[][],\n contracts: EmailRecoveryContracts = DEFAULT_EMAIL_RECOVERY_CONTRACTS\n): Promise<ActionArgs[]> {\n let hasContract = false;\n try {\n const code = await nearClient.viewCode(accountId);\n hasContract = !!code && code.byteLength > 0;\n } catch {\n hasContract = false;\n }\n\n const {\n emailRecovererGlobalContract,\n zkEmailVerifierContract,\n emailDkimVerifierContract,\n } = contracts;\n\n return hasContract\n ? [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'set_recovery_emails',\n args: {\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ]\n : [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'init_email_recovery',\n args: {\n zk_email_verifier: zkEmailVerifierContract,\n email_dkim_verifier: emailDkimVerifierContract,\n policy: null,\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ];\n}\n\nexport async function fetchNonceBlockHashAndHeight({ nearClient, nearPublicKeyStr, nearAccountId }: {\n nearClient: NearClient,\n nearPublicKeyStr: string,\n nearAccountId: AccountId\n}): Promise<TransactionContext> {\n // Get access key and transaction block info concurrently\n const [accessKeyInfo, txBlockInfo] = await Promise.all([\n nearClient.viewAccessKey(nearAccountId, nearPublicKeyStr)\n .catch(e => { throw new Error(`Failed to fetch Access Key`) }),\n nearClient.viewBlock({ finality: 'final' })\n .catch(e => { throw new Error(`Failed to fetch Block Info`) })\n ]);\n if (!accessKeyInfo || accessKeyInfo.nonce === undefined) {\n throw new Error(`Access key not found or invalid for account ${nearAccountId} with public key ${nearPublicKeyStr}. Response: ${JSON.stringify(accessKeyInfo)}`);\n }\n const nextNonce = (BigInt(accessKeyInfo.nonce) + BigInt(1)).toString();\n const txBlockHeight = String(txBlockInfo.header.height);\n const txBlockHash = txBlockInfo.header.hash; // Keep original base58 string\n\n return {\n nearPublicKeyStr,\n accessKeyInfo,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n };\n}\n\n// ===========================\n// REGISTRATION PRE-CHECK CALL\n// ===========================\n\nexport interface CheckCanRegisterUserResult {\n success: boolean;\n verified: boolean;\n logs: string[];\n error?: string;\n}\n\n/**\n * View-only registration pre-check.\n *\n * Calls the contract's `check_can_register_user` view method with VRF data\n * derived from the provided VRF challenge and a serialized WebAuthn\n * registration credential (typically with PRF outputs embedded).\n */\nexport async function checkCanRegisterUserContractCall({\n nearClient,\n contractId,\n vrfChallenge,\n credential,\n authenticatorOptions,\n}: {\n nearClient: NearClient;\n contractId: string;\n vrfChallenge: VRFChallenge;\n credential: WebAuthnRegistrationCredential;\n authenticatorOptions?: AuthenticatorOptions;\n}): Promise<CheckCanRegisterUserResult> {\n try {\n const vrfData = {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n };\n\n const args = {\n vrf_data: vrfData,\n webauthn_registration: credential,\n authenticator_options: authenticatorOptions,\n };\n\n const response = await nearClient.callFunction<typeof args, any>(\n contractId,\n 'check_can_register_user',\n args,\n );\n\n const verified = !!response?.verified;\n return {\n success: true,\n verified,\n logs: [],\n error: verified ? undefined : 'Contract registration check failed',\n };\n } catch (err: unknown) {\n return {\n success: false,\n verified: false,\n logs: [],\n error: errorMessage(err) || 'Failed to call check_can_register_user',\n };\n }\n}\n\n\n/**\n * Verify authentication response through relay server\n * Routes the request to relay server which calls the web3authn contract for verification\n * and issues a JWT or session credential\n */\nexport async function verifyAuthenticationResponse(\n relayServerUrl: string,\n routePath: string,\n sessionKind: 'jwt' | 'cookie',\n vrfChallenge: VRFChallenge,\n webauthnAuthentication: WebAuthnAuthenticationCredential\n): Promise<{\n success: boolean;\n verified?: boolean;\n jwt?: string;\n sessionCredential?: any;\n error?: string;\n contractResponse?: any;\n}> {\n try {\n // Map VRFChallenge into server ContractVrfData shape (number arrays)\n const toBytes = (b64u: string | undefined): number[] => {\n if (!b64u) return [];\n return Array.from(base64UrlDecode(b64u));\n };\n const vrf_data = {\n vrf_input_data: toBytes(vrfChallenge.vrfInput),\n vrf_output: toBytes(vrfChallenge.vrfOutput),\n vrf_proof: toBytes(vrfChallenge.vrfProof),\n public_key: toBytes(vrfChallenge.vrfPublicKey),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight || 0),\n block_hash: toBytes(vrfChallenge.blockHash),\n };\n\n // Normalize authenticatorAttachment and userHandle to null for server schema\n const webauthn_authentication = {\n ...webauthnAuthentication,\n authenticatorAttachment: webauthnAuthentication.authenticatorAttachment ?? null,\n response: {\n ...webauthnAuthentication.response,\n userHandle: webauthnAuthentication.response.userHandle ?? null,\n }\n };\n\n const url = `${relayServerUrl.replace(/\\/$/, '')}${routePath.startsWith('/') ? routePath : `/${routePath}`}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: sessionKind === 'cookie' ? 'include' : 'omit',\n body: JSON.stringify({\n sessionKind: sessionKind,\n vrf_data,\n webauthn_authentication,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `HTTP ${response.status}: ${errorText}`,\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n verified: result.verified,\n jwt: result.jwt,\n sessionCredential: result.sessionCredential,\n contractResponse: result.contractResponse,\n };\n } catch (error: any) {\n return {\n success: false,\n error: error.message || 'Failed to verify authentication response',\n };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"rpcCalls.js","names":["error: any","addKeyTxResult: FinalExecutionOutcome","storeDeviceLinkingTxResult: FinalExecutionOutcome","txError: any","err: unknown"],"sources":["../../../../../../src/core/rpcCalls.ts"],"sourcesContent":["/**\n * Consolidated NEAR Contract Calls\n *\n * This file contains all the NEAR contract calls made to the web3authn contract\n * throughout the passkey SDK. It provides a centralized location for all\n * contract interactions and makes it easier to maintain and update contract\n * call patterns.\n */\n\nimport type { FinalExecutionOutcome } from '@near-js/types';\nimport type { NearClient, SignedTransaction } from './NearClient';\nimport type { ContractStoredAuthenticator } from './TatchiPasskey/recoverAccount';\nimport type { PasskeyManagerContext } from './TatchiPasskey';\nimport type { AccountId } from './types/accountIds';\nimport type { DeviceLinkingSSEEvent } from './types/sdkSentEvents';\nimport type {\n StoredAuthenticator,\n WebAuthnRegistrationCredential,\n WebAuthnAuthenticationCredential\n} from './types/webauthn';\n\nimport { ActionPhase, DeviceLinkingPhase, DeviceLinkingStatus } from './types/sdkSentEvents';\nimport { ActionType, type ActionArgs } from './types/actions';\nimport { VRFChallenge } from './types/vrf-worker';\nimport { DEFAULT_WAIT_STATUS, TransactionContext } from './types/rpc';\nimport type { AuthenticatorOptions } from './types/authenticatorOptions';\nimport type { ConfirmationConfig } from './types/signer-worker';\nimport { base64UrlDecode, base64UrlEncode } from '../utils/encoders';\nimport { errorMessage } from '../utils/errors';\nimport type { EmailRecoveryContracts } from './types/tatchi';\nimport { DEFAULT_EMAIL_RECOVERY_CONTRACTS } from './defaultConfigs';\n\n// ===========================\n// CONTRACT CALL RESPONSES\n// ===========================\n\nexport interface DeviceLinkingResult {\n linkedAccountId: string;\n deviceNumber: number;\n}\n\nexport interface CredentialIdsResult {\n credentialIds: string[];\n}\n\nexport interface AuthenticatorsResult {\n authenticators: Array<[string, ContractStoredAuthenticator]>;\n}\n\nexport type EmailRecoveryVerificationResult = {\n verified: boolean;\n account_id?: string;\n new_public_key?: string;\n transaction_hash?: string;\n error_code?: string;\n error_message?: string;\n};\n\nexport async function getEmailRecoveryVerificationResult(\n nearClient: NearClient,\n dkimVerifierAccountId: string,\n verificationViewMethod: string,\n requestId: string\n): Promise<EmailRecoveryVerificationResult | null> {\n return await nearClient.view<{ request_id: string }, EmailRecoveryVerificationResult | null>({\n account: dkimVerifierAccountId,\n method: verificationViewMethod,\n args: { request_id: requestId },\n });\n}\n\n// ===========================\n// DEVICE LINKING CONTRACT CALLS\n// ===========================\n\n/**\n * Query the contract to get the account linked to a device public key\n * Used in device linking flow to check if a device key has been added\n *\n * NEAR does not provide a way to lookup the AccountID an access key has access to.\n * So we store a temporary mapping in the contract to lookup pubkey -> account ID.\n */\nexport async function getDeviceLinkingAccountContractCall(\n nearClient: NearClient,\n contractId: string,\n devicePublicKey: string\n): Promise<DeviceLinkingResult | null> {\n try {\n const result = await nearClient.callFunction<\n { device_public_key: string },\n [string, number | string]\n >(\n contractId,\n 'get_device_linking_account',\n { device_public_key: devicePublicKey }\n );\n\n // Handle different result formats\n if (result && Array.isArray(result) && result.length >= 2) {\n const [linkedAccountId, deviceNumberRaw] = result;\n const deviceNumber = Number(deviceNumberRaw);\n if (!Number.isSafeInteger(deviceNumber) || deviceNumber < 0) {\n console.warn(\n 'Invalid deviceNumber returned from get_device_linking_account:',\n deviceNumberRaw\n );\n return null;\n }\n return {\n linkedAccountId,\n deviceNumber\n };\n }\n\n return null;\n } catch (error: any) {\n console.warn('Failed to get device linking account:', error.message);\n return null;\n }\n}\n\n// ===========================\n// DEVICE LINKING TRANSACTION CALLS\n// ===========================\n\n/**\n * Execute device1's linking transactions (AddKey + Contract mapping)\n * This function signs and broadcasts both transactions required for device linking\n */\nexport async function executeDeviceLinkingContractCalls({\n context,\n device1AccountId,\n device2PublicKey,\n nextNonce,\n nextNextNonce,\n nextNextNextNonce,\n txBlockHash,\n vrfChallenge,\n onEvent,\n confirmationConfigOverride,\n confirmerText,\n}: {\n context: PasskeyManagerContext,\n device1AccountId: AccountId,\n device2PublicKey: string,\n nextNonce: string,\n nextNextNonce: string,\n nextNextNextNonce: string,\n txBlockHash: string,\n vrfChallenge: VRFChallenge,\n onEvent?: (event: DeviceLinkingSSEEvent) => void;\n confirmationConfigOverride?: Partial<ConfirmationConfig>;\n confirmerText?: { title?: string; body?: string };\n}): Promise<{\n addKeyTxResult: FinalExecutionOutcome;\n storeDeviceLinkingTxResult: FinalExecutionOutcome;\n signedDeleteKeyTransaction: SignedTransaction\n}> {\n\n // Sign three transactions with one PRF authentication\n const signedTransactions = await context.webAuthnManager.signTransactionsWithActions({\n rpcCall: {\n contractId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n nearRpcUrl: context.webAuthnManager.tatchiPasskeyConfigs.nearRpcUrl,\n nearAccountId: device1AccountId\n },\n confirmationConfigOverride,\n title: confirmerText?.title,\n body: confirmerText?.body,\n transactions: [\n // Transaction 1: AddKey - Add Device2's key to Device1's account\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.AddKey,\n public_key: device2PublicKey,\n access_key: JSON.stringify({\n // NEAR-style AccessKey JSON shape, matching near-api-js:\n // { nonce: number, permission: { FullAccess: {} } }\n nonce: 0,\n permission: { FullAccess: {} },\n }),\n }],\n nonce: nextNonce,\n },\n // Transaction 2: Store temporary mapping in contract so Device2 can lookup Device1's accountID.\n {\n receiverId: context.webAuthnManager.tatchiPasskeyConfigs.contractId,\n actions: [{\n action_type: ActionType.FunctionCall,\n method_name: 'store_device_linking_mapping',\n args: JSON.stringify({\n device_public_key: device2PublicKey,\n target_account_id: device1AccountId,\n }),\n gas: '30000000000000', // 30 TGas for device linking with yield promise automatic cleanup\n deposit: '0'\n }],\n nonce: nextNextNonce,\n },\n // Transaction 3: Remove Device2's temporary key if it fails to complete linking after a timeout\n {\n receiverId: device1AccountId,\n actions: [{\n action_type: ActionType.DeleteKey,\n public_key: device2PublicKey\n }],\n nonce: nextNextNextNonce,\n }\n ],\n onEvent: (progress) => {\n // Bridge all action progress events to the parent so the wallet iframe overlay\n // can expand during user confirmation in wallet-iframe mode.\n try { onEvent?.(progress as any); } catch { }\n // Keep existing mapping for device linking semantics; surface signing as a loading state\n if (progress.phase == ActionPhase.STEP_6_TRANSACTION_SIGNING_COMPLETE) {\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.PROGRESS,\n message: progress.message || 'Transaction signing in progress...'\n })\n }\n }\n });\n\n if (!signedTransactions[0].signedTransaction) {\n throw new Error('AddKey transaction signing failed');\n }\n if (!signedTransactions[1].signedTransaction) {\n throw new Error('Contract mapping transaction signing failed');\n }\n if (!signedTransactions[2].signedTransaction) {\n throw new Error('DeleteKey transaction signing failed');\n }\n\n // Broadcast just the first 2 transactions: addKey and store device linking mapping\n let addKeyTxResult: FinalExecutionOutcome;\n let storeDeviceLinkingTxResult: FinalExecutionOutcome;\n try {\n console.debug('LinkDeviceFlow: AddKey transaction details:', {\n receiverId: signedTransactions[0].signedTransaction.transaction.receiverId,\n actions: signedTransactions[0].signedTransaction.transaction.actions || [],\n transactionKeys: Object.keys(signedTransactions[0].signedTransaction.transaction),\n });\n\n addKeyTxResult = await context.nearClient.sendTransaction(\n signedTransactions[0].signedTransaction,\n DEFAULT_WAIT_STATUS.linkDeviceAddKey\n );\n console.log('LinkDeviceFlow: AddKey transaction result:', addKeyTxResult?.transaction?.hash);\n\n // Send success events immediately after AddKey succeeds\n onEvent?.({\n step: 3,\n phase: DeviceLinkingPhase.STEP_3_AUTHORIZATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `AddKey transaction completed successfully!`\n });\n\n // Check if contract mapping transaction is valid before attempting to broadcast\n const contractTx = signedTransactions[1].signedTransaction;\n console.log('LinkDeviceFlow: Contract mapping transaction details:', {\n receiverId: contractTx.transaction.receiverId,\n actions: (contractTx.transaction.actions || []).length\n });\n\n // Standard timeout since nonce conflict should be resolved by the 2s delay\n storeDeviceLinkingTxResult = await context.nearClient.sendTransaction(\n contractTx,\n DEFAULT_WAIT_STATUS.linkDeviceAccountMapping\n );\n\n } catch (txError: any) {\n console.error('LinkDeviceFlow: Transaction broadcasting failed:', txError);\n throw new Error(`Transaction broadcasting failed: ${txError.message}`);\n }\n\n onEvent?.({\n step: 6,\n phase: DeviceLinkingPhase.STEP_6_REGISTRATION,\n status: DeviceLinkingStatus.SUCCESS,\n message: `Device linking completed successfully!`\n });\n\n return {\n addKeyTxResult,\n storeDeviceLinkingTxResult,\n signedDeleteKeyTransaction: signedTransactions[2].signedTransaction\n };\n}\n\n// ===========================\n// ACCOUNT RECOVERY CONTRACT CALLS\n// ===========================\n\n/**\n * Get credential IDs associated with an account from the contract\n * Used in account recovery to discover available credentials\n */\nexport async function getCredentialIdsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<string[]> {\n try {\n const credentialIds = await nearClient.callFunction<{ account_id: AccountId }, string[]>(\n contractId,\n 'get_credential_ids_by_account',\n { account_id: accountId }\n );\n return credentialIds || [];\n } catch (error: any) {\n console.warn('Failed to fetch credential IDs from contract:', error.message);\n return [];\n }\n}\n\n/**\n * Get all authenticators stored for a user from the contract\n * Used in account recovery to sync authenticator data\n */\nexport async function getAuthenticatorsByUser(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<[string, ContractStoredAuthenticator][]> {\n try {\n const authenticatorsResult = await nearClient.view<{ user_id: AccountId }, [string, ContractStoredAuthenticator][]>({\n account: contractId,\n method: 'get_authenticators_by_user',\n args: { user_id: accountId }\n });\n\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult;\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\nexport async function syncAuthenticatorsContractCall(\n nearClient: NearClient,\n contractId: string,\n accountId: AccountId\n): Promise<Array<{ credentialId: string, authenticator: StoredAuthenticator }>> {\n try {\n const authenticatorsResult = await getAuthenticatorsByUser(nearClient, contractId, accountId);\n if (authenticatorsResult && Array.isArray(authenticatorsResult)) {\n return authenticatorsResult.map(([credentialId, contractAuthenticator]) => {\n console.log(`Contract authenticator device_number for ${credentialId}:`, contractAuthenticator.device_number);\n\n const transports = Array.isArray(contractAuthenticator.transports)\n ? contractAuthenticator.transports\n : [];\n\n const registered = (() => {\n const raw = String((contractAuthenticator as any).registered ?? '');\n if (!raw) return new Date(0);\n if (/^\\d+$/.test(raw)) {\n const ts = Number(raw);\n return Number.isFinite(ts) ? new Date(ts) : new Date(0);\n }\n const d = new Date(raw);\n return Number.isFinite(d.getTime()) ? d : new Date(0);\n })();\n\n const vrfPublicKeys = (() => {\n const raw = (contractAuthenticator as any).vrf_public_keys;\n if (!raw) return undefined;\n if (Array.isArray(raw) && raw.length > 0 && typeof raw[0] === 'string') {\n return raw as string[];\n }\n if (Array.isArray(raw)) {\n return raw\n .map((entry: unknown) => {\n if (!entry) return null;\n if (entry instanceof Uint8Array) return base64UrlEncode(entry);\n if (Array.isArray(entry)) return base64UrlEncode(new Uint8Array(entry));\n return null;\n })\n .filter((x): x is string => typeof x === 'string' && x.length > 0);\n }\n return undefined;\n })();\n\n return {\n credentialId,\n authenticator: {\n credentialId,\n credentialPublicKey: new Uint8Array(contractAuthenticator.credential_public_key),\n transports,\n userId: accountId,\n name: `Device ${contractAuthenticator.device_number} Authenticator`,\n registered,\n // Store the actual device number from contract (no fallback)\n deviceNumber: contractAuthenticator.device_number,\n vrfPublicKeys\n }\n };\n });\n }\n return [];\n } catch (error: any) {\n console.warn('Failed to fetch authenticators from contract:', error.message);\n return [];\n }\n}\n\n// ===========================\n// RECOVERY EMAIL CONTRACT CALLS\n// ===========================\n\n/**\n * Fetch on-chain recovery email hashes from the per-account contract.\n * Returns [] when no contract is deployed or on failure.\n */\nexport async function getRecoveryEmailHashesContractCall(\n nearClient: NearClient,\n accountId: AccountId\n): Promise<number[][]> {\n try {\n const code = await nearClient.viewCode(accountId);\n const hasContract = !!code && code.byteLength > 0;\n if (!hasContract) return [];\n\n const hashes = await nearClient.view<Record<string, never>, number[][]>({\n account: accountId,\n method: 'get_recovery_emails',\n args: {} as Record<string, never>,\n });\n\n return Array.isArray(hashes) ? (hashes as number[][]) : [];\n } catch (error) {\n console.error('[rpcCalls] Failed to fetch recovery email hashes', error);\n return [];\n }\n}\n\n/**\n * Build action args to update on-chain recovery emails for an account.\n * If the per-account contract is missing, deploy/attach the global recoverer via `init_email_recovery`.\n */\nexport async function buildSetRecoveryEmailsActions(\n nearClient: NearClient,\n accountId: AccountId,\n recoveryEmailHashes: number[][],\n contracts: EmailRecoveryContracts = DEFAULT_EMAIL_RECOVERY_CONTRACTS\n): Promise<ActionArgs[]> {\n let hasContract = false;\n try {\n const code = await nearClient.viewCode(accountId);\n hasContract = !!code && code.byteLength > 0;\n } catch {\n hasContract = false;\n }\n\n const {\n emailRecovererGlobalContract,\n zkEmailVerifierContract,\n emailDkimVerifierContract,\n } = contracts;\n\n return hasContract\n ? [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'set_recovery_emails',\n args: {\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ]\n : [\n {\n type: ActionType.UseGlobalContract,\n accountId: emailRecovererGlobalContract,\n },\n {\n type: ActionType.FunctionCall,\n methodName: 'init_email_recovery',\n args: {\n zk_email_verifier: zkEmailVerifierContract,\n email_dkim_verifier: emailDkimVerifierContract,\n policy: null,\n recovery_emails: recoveryEmailHashes,\n },\n gas: '80000000000000',\n deposit: '0',\n },\n ];\n}\n\nexport async function fetchNonceBlockHashAndHeight({ nearClient, nearPublicKeyStr, nearAccountId }: {\n nearClient: NearClient,\n nearPublicKeyStr: string,\n nearAccountId: AccountId\n}): Promise<TransactionContext> {\n // Get access key and transaction block info concurrently\n const [accessKeyInfo, txBlockInfo] = await Promise.all([\n nearClient.viewAccessKey(nearAccountId, nearPublicKeyStr)\n .catch(e => { throw new Error(`Failed to fetch Access Key`) }),\n nearClient.viewBlock({ finality: 'final' })\n .catch(e => { throw new Error(`Failed to fetch Block Info`) })\n ]);\n if (!accessKeyInfo || accessKeyInfo.nonce === undefined) {\n throw new Error(`Access key not found or invalid for account ${nearAccountId} with public key ${nearPublicKeyStr}. Response: ${JSON.stringify(accessKeyInfo)}`);\n }\n const nextNonce = (BigInt(accessKeyInfo.nonce) + BigInt(1)).toString();\n const txBlockHeight = String(txBlockInfo.header.height);\n const txBlockHash = txBlockInfo.header.hash; // Keep original base58 string\n\n return {\n nearPublicKeyStr,\n accessKeyInfo,\n nextNonce,\n txBlockHeight,\n txBlockHash,\n };\n}\n\n// ===========================\n// REGISTRATION PRE-CHECK CALL\n// ===========================\n\nexport interface CheckCanRegisterUserResult {\n success: boolean;\n verified: boolean;\n logs: string[];\n error?: string;\n}\n\n/**\n * View-only registration pre-check.\n *\n * Calls the contract's `check_can_register_user` view method with VRF data\n * derived from the provided VRF challenge and a serialized WebAuthn\n * registration credential (typically with PRF outputs embedded).\n */\nexport async function checkCanRegisterUserContractCall({\n nearClient,\n contractId,\n vrfChallenge,\n credential,\n authenticatorOptions,\n}: {\n nearClient: NearClient;\n contractId: string;\n vrfChallenge: VRFChallenge;\n credential: WebAuthnRegistrationCredential;\n authenticatorOptions?: AuthenticatorOptions;\n}): Promise<CheckCanRegisterUserResult> {\n try {\n const vrfData = {\n vrf_input_data: Array.from(base64UrlDecode(vrfChallenge.vrfInput)),\n vrf_output: Array.from(base64UrlDecode(vrfChallenge.vrfOutput)),\n vrf_proof: Array.from(base64UrlDecode(vrfChallenge.vrfProof)),\n public_key: Array.from(base64UrlDecode(vrfChallenge.vrfPublicKey)),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight),\n block_hash: Array.from(base64UrlDecode(vrfChallenge.blockHash)),\n };\n\n const args = {\n vrf_data: vrfData,\n webauthn_registration: credential,\n authenticator_options: authenticatorOptions,\n };\n\n const response = await nearClient.callFunction<typeof args, any>(\n contractId,\n 'check_can_register_user',\n args,\n );\n\n const verified = !!response?.verified;\n return {\n success: true,\n verified,\n logs: [],\n error: verified ? undefined : 'Contract registration check failed',\n };\n } catch (err: unknown) {\n return {\n success: false,\n verified: false,\n logs: [],\n error: errorMessage(err) || 'Failed to call check_can_register_user',\n };\n }\n}\n\n\n/**\n * Verify authentication response through relay server\n * Routes the request to relay server which calls the web3authn contract for verification\n * and issues a JWT or session credential\n */\nexport async function verifyAuthenticationResponse(\n relayServerUrl: string,\n routePath: string,\n sessionKind: 'jwt' | 'cookie',\n vrfChallenge: VRFChallenge,\n webauthnAuthentication: WebAuthnAuthenticationCredential\n): Promise<{\n success: boolean;\n verified?: boolean;\n jwt?: string;\n sessionCredential?: any;\n error?: string;\n contractResponse?: any;\n}> {\n try {\n // Map VRFChallenge into server ContractVrfData shape (number arrays)\n const toBytes = (b64u: string | undefined): number[] => {\n if (!b64u) return [];\n return Array.from(base64UrlDecode(b64u));\n };\n const vrf_data = {\n vrf_input_data: toBytes(vrfChallenge.vrfInput),\n vrf_output: toBytes(vrfChallenge.vrfOutput),\n vrf_proof: toBytes(vrfChallenge.vrfProof),\n public_key: toBytes(vrfChallenge.vrfPublicKey),\n user_id: vrfChallenge.userId,\n rp_id: vrfChallenge.rpId,\n block_height: Number(vrfChallenge.blockHeight || 0),\n block_hash: toBytes(vrfChallenge.blockHash),\n };\n\n // Normalize authenticatorAttachment and userHandle to null for server schema\n const webauthn_authentication = {\n ...webauthnAuthentication,\n authenticatorAttachment: webauthnAuthentication.authenticatorAttachment ?? null,\n response: {\n ...webauthnAuthentication.response,\n userHandle: webauthnAuthentication.response.userHandle ?? null,\n }\n };\n\n const url = `${relayServerUrl.replace(/\\/$/, '')}${routePath.startsWith('/') ? routePath : `/${routePath}`}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n credentials: sessionKind === 'cookie' ? 'include' : 'omit',\n body: JSON.stringify({\n sessionKind: sessionKind,\n vrf_data,\n webauthn_authentication,\n }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n return {\n success: false,\n error: `HTTP ${response.status}: ${errorText}`,\n };\n }\n\n const result = await response.json();\n return {\n success: true,\n verified: result.verified,\n jwt: result.jwt,\n sessionCredential: result.sessionCredential,\n contractResponse: result.contractResponse,\n };\n } catch (error: any) {\n return {\n success: false,\n error: error.message || 'Failed to verify authentication response',\n };\n }\n}\n"],"mappings":"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"}