@veridex/sdk 1.1.1 → 1.1.3
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/{EVMClient-DtqvdfUP.d.mts → EVMClient-Bmy9czkE.d.mts} +2 -0
- package/dist/chains/avalanche/index.d.mts +1 -1
- package/dist/chains/avalanche/index.js +81 -19
- package/dist/chains/avalanche/index.js.map +1 -1
- package/dist/chains/avalanche/index.mjs +2 -2
- package/dist/chains/evm/index.d.mts +3 -3
- package/dist/chains/evm/index.js +81 -19
- package/dist/chains/evm/index.js.map +1 -1
- package/dist/chains/evm/index.mjs +1 -1
- package/dist/chains/stacks/index.d.mts +1 -1
- package/dist/chains/starknet/index.d.mts +1 -1
- package/dist/chains/stellar/index.d.mts +312 -0
- package/dist/chains/stellar/index.js +300 -0
- package/dist/chains/stellar/index.js.map +1 -0
- package/dist/chains/stellar/index.mjs +260 -0
- package/dist/chains/stellar/index.mjs.map +1 -0
- package/dist/chains/sui/index.d.mts +1 -1
- package/dist/{chunk-PEGOXMBU.mjs → chunk-6JULIESG.mjs} +2 -2
- package/dist/{chunk-YBN2VC6E.mjs → chunk-E5HHE7IW.mjs} +82 -20
- package/dist/chunk-E5HHE7IW.mjs.map +1 -0
- package/dist/{index-CySMITQ9.d.mts → index-CKKUV4J7.d.mts} +2 -2
- package/dist/index.d.mts +5 -4
- package/dist/index.js +89 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -3
- package/dist/index.mjs.map +1 -1
- package/dist/{types-DWx-5jmz.d.mts → types-C564CfsE.d.mts} +21 -1
- package/package.json +8 -1
- package/dist/chunk-YBN2VC6E.mjs.map +0 -1
- /package/dist/{chunk-PEGOXMBU.mjs.map → chunk-6JULIESG.mjs.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/chains/stellar/index.ts","../../../src/chains/stellar/StellarPasskeySigner.ts","../../../src/utils.ts","../../../src/chains/stellar/types.ts","../../../src/chains/stellar/SmartAccount.ts","../../../src/chains/stellar/VeridexStellarWalletModule.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK — Stellar chain module\n *\n * Provides:\n * - `StellarPasskeySigner`: SEP-43-compatible passkey signer\n * - `VeridexStellarWalletModule`: Stellar-Wallets-Kit `ModuleInterface`\n * - `deriveSmartAccountId`: deterministic Soroban smart-account derivation\n */\n\nexport { StellarPasskeySigner } from './StellarPasskeySigner.js';\nexport type { StellarPasskeySignerOptions } from './StellarPasskeySigner.js';\n\nexport {\n VeridexStellarWalletModule,\n VERIDEX_PASSKEY_ID,\n StellarNetworks,\n} from './VeridexStellarWalletModule.js';\nexport type { VeridexStellarWalletModuleOptions } from './VeridexStellarWalletModule.js';\n\nexport { deriveSmartAccountId } from './SmartAccount.js';\n\nexport {\n StellarModuleType,\n} from './types.js';\nexport type {\n StellarWalletModuleInterface,\n StellarKitError,\n VeridexStellarConfig,\n PasskeyAuthAssertion,\n} from './types.js';\n","/**\n * Veridex Protocol SDK — Stellar Passkey Signer\n *\n * Bridges Veridex's WebAuthn `PasskeyManager` to the SEP-43 signing surface\n * expected by Soroban smart accounts (and the Stellar-Wallets-Kit\n * `ModuleInterface`).\n *\n * Design:\n * - The signer treats every SEP-43 signing call (transaction / auth entry\n * / message) as a request to produce a WebAuthn assertion over the\n * SHA-256 of a canonical preimage.\n * - For a transaction we hash `network_id || tagged_tx_envelope` per the\n * XDR-hash spec; for an auth entry we hash the\n * `HashIdPreimageSorobanAuthorization`; for a message we hash the bytes\n * directly.\n * - The returned `signedTxXdr` / `signedAuthEntry` strings are\n * base64-encoded JSON containers carrying the assertion. The downstream\n * Soroban smart-account contract (`__check_auth`) is responsible for\n * parsing the container, verifying secp256r1, and authorizing.\n *\n * This separation lets `@veridex/sdk` ship without a hard dependency on\n * `@stellar/stellar-sdk`. Consumers who want full XDR-aware signing can\n * subclass and override `hashTransactionXdr` / `hashAuthEntry`.\n */\n\nimport { sha256 } from '@noble/hashes/sha256';\nimport { PasskeyManager } from '../../core/PasskeyManager.js';\nimport type { PasskeyCredential } from '../../core/PasskeyManager.js';\nimport { base64URLDecode } from '../../utils.js';\nimport {\n StellarNetworks,\n type PasskeyAuthAssertion,\n type VeridexStellarConfig,\n} from './types.js';\nimport { deriveSmartAccountId } from './SmartAccount.js';\n\nexport interface StellarPasskeySignerOptions {\n passkey: PasskeyManager;\n credential?: PasskeyCredential;\n config?: VeridexStellarConfig;\n}\n\nexport class StellarPasskeySigner {\n private readonly passkey: PasskeyManager;\n private credential?: PasskeyCredential;\n private readonly network: StellarNetworks;\n private readonly smartAccountContractId?: string;\n\n constructor(opts: StellarPasskeySignerOptions) {\n this.passkey = opts.passkey;\n this.credential = opts.credential;\n this.network = opts.config?.network ?? StellarNetworks.TESTNET;\n this.smartAccountContractId = opts.config?.smartAccountContractId;\n }\n\n /**\n * Returns the Soroban smart-account address (C-address-derivable hex)\n * associated with the active passkey. If a fixed contract id was\n * configured we return it verbatim; otherwise we derive deterministically.\n */\n async getAddress(skipRequestAccess = false): Promise<{ address: string }> {\n if (this.smartAccountContractId) {\n return { address: this.smartAccountContractId };\n }\n const cred = await this.ensureCredential(skipRequestAccess);\n const id = deriveSmartAccountId(cred.keyHash, this.network);\n return { address: id };\n }\n\n /**\n * Produce a SEP-43 `signedTxXdr` for the given transaction envelope XDR.\n *\n * Because we do not bundle `@stellar/stellar-sdk` we hash the XDR's\n * binary form prefixed with the network passphrase. Consumers that need\n * canonical Stellar transaction hashes should preprocess `xdr` to the\n * spec-compliant preimage before calling, or override this method.\n */\n async signTransaction(\n xdr: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedTxXdr: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const passphrase = opts?.networkPassphrase ?? this.network;\n const challenge = this.hashTransactionXdr(xdr, passphrase);\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('tx', xdr, assertion);\n const { address } = await this.getAddress(true);\n return { signedTxXdr: container, signerAddress: opts?.address ?? address };\n }\n\n /**\n * Sign a Soroban `HashIdPreimageSorobanAuthorization` XDR. The auth\n * entry payload is hashed and wrapped identically to a transaction.\n */\n async signAuthEntry(\n authEntry: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedAuthEntry: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const passphrase = opts?.networkPassphrase ?? this.network;\n const challenge = this.hashAuthEntry(authEntry, passphrase);\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('auth', authEntry, assertion);\n const { address } = await this.getAddress(true);\n return { signedAuthEntry: container, signerAddress: opts?.address ?? address };\n }\n\n /**\n * Sign an arbitrary message per SEP-43 `signMessage`.\n */\n async signMessage(\n message: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedMessage: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const challenge = sha256(new TextEncoder().encode(message));\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('msg', message, assertion);\n const { address } = await this.getAddress(true);\n return { signedMessage: container, signerAddress: opts?.address ?? address };\n }\n\n // ------------------------------------------------------------------\n // Internals\n // ------------------------------------------------------------------\n\n protected hashTransactionXdr(xdr: string, networkPassphrase: string): Uint8Array {\n const passphraseHash = sha256(new TextEncoder().encode(networkPassphrase));\n const xdrBytes = this.decodeBase64(xdr);\n const buf = new Uint8Array(passphraseHash.length + xdrBytes.length);\n buf.set(passphraseHash, 0);\n buf.set(xdrBytes, passphraseHash.length);\n return sha256(buf);\n }\n\n protected hashAuthEntry(authEntry: string, networkPassphrase: string): Uint8Array {\n return this.hashTransactionXdr(authEntry, networkPassphrase);\n }\n\n private async signChallenge(\n challenge: Uint8Array,\n credential: PasskeyCredential,\n ): Promise<PasskeyAuthAssertion> {\n const sig = await this.passkey.sign(challenge);\n return {\n keyHash: credential.keyHash,\n authenticatorData: sig.authenticatorData,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: sig.challengeIndex,\n typeIndex: sig.typeIndex,\n signatureR: '0x' + sig.r.toString(16).padStart(64, '0'),\n signatureS: '0x' + sig.s.toString(16).padStart(64, '0'),\n };\n }\n\n private async ensureCredential(skipRequestAccess: boolean): Promise<PasskeyCredential> {\n if (this.credential) return this.credential;\n if (skipRequestAccess) {\n throw new Error(\n 'StellarPasskeySigner: no credential cached. Call passkey.authenticate() ' +\n 'first or pass `credential` to the constructor.',\n );\n }\n const { credential } = await this.passkey.authenticate();\n this.credential = credential;\n return credential;\n }\n\n private encodeAssertionContainer(\n kind: 'tx' | 'auth' | 'msg',\n payload: string,\n assertion: PasskeyAuthAssertion,\n ): string {\n const container = {\n v: 1,\n kind,\n payload,\n assertion,\n };\n const json = JSON.stringify(container);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(json, 'utf8').toString('base64');\n }\n // Browser fallback.\n return btoa(unescape(encodeURIComponent(json)));\n }\n\n private decodeBase64(input: string): Uint8Array {\n try {\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(input, 'base64'));\n }\n const binary = atob(input);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n } catch {\n // Fall back to base64url if standard base64 fails.\n return base64URLDecode(input);\n }\n }\n}\n","/**\n * Veridex Protocol SDK - Utility Functions\n */\n\nimport { ethers } from 'ethers';\nimport type { ChainConfig } from './types.js';\nimport { TESTNET_CHAINS, MAINNET_CHAINS } from './constants.js';\n\n// ============================================================================\n// Base64URL Encoding/Decoding (WebAuthn compatible)\n// ============================================================================\n\n/**\n * Base64URL encode a buffer\n */\nexport function base64URLEncode(buffer: Uint8Array): string {\n // Convert Uint8Array to base64 using browser APIs\n const bytes = Array.from(buffer);\n const binary = String.fromCharCode(...bytes);\n const base64 = btoa(binary);\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Base64URL decode a string\n */\nexport function base64URLDecode(str: string): Uint8Array {\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64 + '='.repeat((4 - (base64.length % 4)) % 4);\n // Use browser's atob for base64 decoding\n const binary = atob(padded);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n// ============================================================================\n// Signature Utilities\n// ============================================================================\n\n/**\n * Parse DER-encoded ECDSA signature to r and s values\n */\nexport function parseDERSignature(signature: Uint8Array): { r: Uint8Array; s: Uint8Array } {\n let offset = 0;\n\n if (signature[offset++] !== 0x30) {\n throw new Error('Invalid signature format');\n }\n\n // Skip total length\n offset++;\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const rLength = signature[offset++];\n if (rLength === undefined) {\n throw new Error('Invalid signature format: missing r length');\n }\n let r = signature.slice(offset, offset + rLength);\n offset += rLength;\n\n // Remove leading zero if present (for positive number representation)\n if (r[0] === 0x00 && r.length > 32) {\n r = r.slice(1);\n }\n // Pad to 32 bytes if needed\n if (r.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(r, 32 - r.length);\n r = padded;\n }\n\n if (signature[offset++] !== 0x02) {\n throw new Error('Invalid signature format');\n }\n\n const sLength = signature[offset++];\n if (sLength === undefined) {\n throw new Error('Invalid signature format: missing s length');\n }\n let s = signature.slice(offset, offset + sLength);\n\n // Remove leading zero if present\n if (s[0] === 0x00 && s.length > 32) {\n s = s.slice(1);\n }\n // Pad to 32 bytes if needed\n if (s.length < 32) {\n const padded = new Uint8Array(32);\n padded.set(s, 32 - s.length);\n s = padded;\n }\n\n return { r, s };\n}\n\n/**\n * Encode signature for Solidity verification\n */\nexport function encodeSignatureForSolidity(r: bigint, s: bigint): string {\n return ethers.solidityPacked(['uint256', 'uint256'], [r, s]);\n}\n\n// ============================================================================\n// Key Hash Utilities\n// ============================================================================\n\n/**\n * Compute key hash from public key coordinates\n */\nexport function computeKeyHash(publicKeyX: bigint, publicKeyY: bigint): string {\n return ethers.keccak256(\n ethers.solidityPacked(['uint256', 'uint256'], [publicKeyX, publicKeyY])\n );\n}\n\n// ============================================================================\n// Chain Utilities\n// ============================================================================\n\n/**\n * Get chain config by name\n */\nexport function getChainConfig(chainName: string, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return chains[chainName];\n}\n\n/**\n * Get chain config by Wormhole chain ID\n */\nexport function getChainByWormholeId(wormholeChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.wormholeChainId === wormholeChainId);\n}\n\n/**\n * Get chain config by EVM chain ID\n */\nexport function getChainByEvmId(evmChainId: number, testnet = true): ChainConfig | undefined {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains).find(chain => chain.chainId === evmChainId);\n}\n\n/**\n * Check if a chain is EVM-compatible\n */\nexport function isEvmChain(wormholeChainId: number): boolean {\n // Non-EVM chains\n const nonEvmChains = new Set([1, 8, 15, 21, 22]); // Solana, Algorand, NEAR, Sui, Aptos\n return !nonEvmChains.has(wormholeChainId);\n}\n\n/**\n * Get all supported chains\n */\nexport function getSupportedChains(testnet = true): ChainConfig[] {\n const chains = testnet ? TESTNET_CHAINS : MAINNET_CHAINS;\n return Object.values(chains);\n}\n\n// ============================================================================\n// Explorer URL Utilities\n// ============================================================================\n\n/**\n * Get transaction explorer URL\n */\nexport function getTxExplorerUrl(chain: ChainConfig, txHash: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n\n // Non-EVM chains have different URL patterns\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/tx/${txHash}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/tx/${txHash}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/txn/${txHash}?network=testnet`;\n default:\n return `${chain.explorerUrl}/tx/${txHash}`;\n }\n}\n\n/**\n * Get address explorer URL\n */\nexport function getAddressExplorerUrl(chain: ChainConfig, address: string): string {\n if (chain.isEvm) {\n return `${chain.explorerUrl}/address/${address}`;\n }\n\n switch (chain.wormholeChainId) {\n case 1: // Solana\n return `${chain.explorerUrl}/address/${address}?cluster=devnet`;\n case 21: // Sui\n return `${chain.explorerUrl}/account/${address}`;\n case 22: // Aptos\n return `${chain.explorerUrl}/account/${address}?network=testnet`;\n default:\n return `${chain.explorerUrl}/address/${address}`;\n }\n}\n\n// ============================================================================\n// Validation Utilities\n// ============================================================================\n\n/**\n * Validate an EVM address\n */\nexport function isValidEvmAddress(address: string): boolean {\n return ethers.isAddress(address);\n}\n\n/**\n * Validate a bytes32 hex string\n */\nexport function isValidBytes32(hex: string): boolean {\n const clean = hex.replace('0x', '');\n return /^[0-9a-fA-F]{64}$/.test(clean);\n}\n\n/**\n * Validate a Wormhole chain ID\n */\nexport function isValidWormholeChainId(chainId: number): boolean {\n // Valid Wormhole chain IDs range from 1 to ~10007 (testnets)\n return chainId >= 1 && chainId <= 50000;\n}\n\n// ============================================================================\n// Retry Utilities\n// ============================================================================\n\n/**\n * Retry a function with exponential backoff\n */\nexport async function retryWithBackoff<T>(\n fn: () => Promise<T>,\n options: {\n maxRetries?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n backoffMultiplier?: number;\n onRetry?: (attempt: number, error: Error) => void;\n } = {}\n): Promise<T> {\n const {\n maxRetries = 5,\n initialDelayMs = 1000,\n maxDelayMs = 30000,\n backoffMultiplier = 2,\n onRetry,\n } = options;\n\n let lastError: Error | undefined;\n let delay = initialDelayMs;\n\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error as Error;\n\n if (attempt < maxRetries) {\n onRetry?.(attempt, lastError);\n await sleep(delay);\n delay = Math.min(delay * backoffMultiplier, maxDelayMs);\n }\n }\n }\n\n throw lastError ?? new Error('Retry failed');\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","/**\n * Veridex Protocol SDK — Stellar chain types\n *\n * Local mirror of the subset of the Stellar-Wallets-Kit `ModuleInterface`\n * contract we implement. We mirror it (rather than importing from\n * `@creit.tech/stellar-wallets-kit`) so `@veridex/sdk` does not gain a hard\n * peer dependency on the kit. Consumers who already depend on the kit can\n * cast our module to the upstream type — the shapes are structurally\n * identical.\n *\n * Upstream reference: `@creit.tech/stellar-wallets-kit` →\n * src/types/mod.ts → `ModuleInterface`\n */\n\nexport enum StellarNetworks {\n PUBLIC = 'Public Global Stellar Network ; September 2015',\n TESTNET = 'Test SDF Network ; September 2015',\n FUTURENET = 'Test SDF Future Network ; October 2022',\n SANDBOX = 'Local Sandbox Stellar Network ; September 2022',\n STANDALONE = 'Standalone Network ; February 2017',\n}\n\nexport enum StellarModuleType {\n HW_WALLET = 'HW_WALLET',\n HOT_WALLET = 'HOT_WALLET',\n BRIDGE_WALLET = 'BRIDGE_WALLET',\n AIR_GAPED_WALLET = 'AIR_GAPED_WALLET',\n}\n\nexport interface StellarKitError {\n code: number;\n message: string;\n ext?: string;\n}\n\n/**\n * Stellar-Wallets-Kit `ModuleInterface` mirror.\n * Only the methods we implement are documented; signature-compatible with\n * the upstream contract.\n */\nexport interface StellarWalletModuleInterface {\n moduleType: StellarModuleType;\n productId: string;\n productName: string;\n productUrl: string;\n productIcon: string;\n\n isAvailable(): Promise<boolean>;\n isPlatformWrapper?(): Promise<boolean>;\n\n getAddress(params?: {\n path?: string;\n skipRequestAccess?: boolean;\n }): Promise<{ address: string }>;\n\n signTransaction(\n xdr: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedTxXdr: string; signerAddress?: string }>;\n\n signAuthEntry(\n authEntry: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedAuthEntry: string; signerAddress?: string }>;\n\n signMessage(\n message: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedMessage: string; signerAddress?: string }>;\n}\n\n/**\n * Veridex-specific configuration for the Stellar passkey signer.\n */\nexport interface VeridexStellarConfig {\n /** Stellar network passphrase. Defaults to TESTNET. */\n network?: StellarNetworks;\n /**\n * Soroban RPC URL (used to resolve the smart-account address or submit\n * transactions when `signAndSubmitTransaction` is invoked).\n */\n rpcUrl?: string;\n /**\n * Optional pre-deployed smart-account contract id (C-address). If\n * provided, `getAddress()` returns this directly. Otherwise the address\n * is derived deterministically from the passkey `keyHash`.\n */\n smartAccountContractId?: string;\n /**\n * Override the deterministic smart-account factory contract. Used for\n * address derivation when `smartAccountContractId` is not set.\n */\n smartAccountFactory?: string;\n}\n\n/**\n * A signed WebAuthn assertion ready to be embedded in a Soroban auth entry.\n *\n * The shape matches what a Soroban smart-account's `__check_auth` entrypoint\n * needs to verify a secp256r1 passkey signature:\n * - `keyHash` identifies which registered passkey signed\n * - `authenticatorData` + `clientDataJSON` are the WebAuthn assertion\n * - `r`, `s` are the secp256r1 signature components\n */\nexport interface PasskeyAuthAssertion {\n keyHash: string;\n authenticatorData: string;\n clientDataJSON: string;\n challengeIndex: number;\n typeIndex: number;\n signatureR: string;\n signatureS: string;\n}\n","/**\n * Veridex Protocol SDK — Soroban smart-account address derivation\n *\n * The Veridex Stellar adapter binds a WebAuthn passkey to a Soroban smart\n * account whose `__check_auth` entry verifies secp256r1 signatures against\n * the passkey's `keyHash`.\n *\n * For the credibility-artifact stage we expose deterministic address\n * derivation only — actual deployment is handled by a separate Soroban\n * factory contract (see `contracts/stellar/` once added). This keeps the\n * SDK chain-agnostic and avoids pulling in the heavy `@stellar/stellar-sdk`\n * runtime.\n */\n\nimport { sha256 } from '@noble/hashes/sha256';\n\n/**\n * Deterministically derive a Soroban contract id (C-address) from a passkey\n * `keyHash`. This mirrors the SEP-0011 Stellar contract-id derivation\n * scheme: contract_id = sha256(networkPassphrase || keyHash || salt).\n *\n * NOTE: This returns a stable 32-byte identifier encoded as hex. To produce\n * a canonical `C...` strkey representation the consumer must encode it with\n * `StrKey.encodeContract` from `@stellar/stellar-sdk`. We deliberately keep\n * the encoding out of `@veridex/sdk` to avoid a hard dependency.\n *\n * @param keyHash - The Veridex passkey keyHash (hex, with or without 0x).\n * @param networkPassphrase - Stellar network passphrase (e.g. testnet).\n * @param salt - Optional 32-byte salt (hex). Defaults to all-zeros.\n * @returns The 32-byte contract id encoded as a 0x-prefixed hex string.\n */\nexport function deriveSmartAccountId(\n keyHash: string,\n networkPassphrase: string,\n salt?: string,\n): string {\n const cleanHash = keyHash.startsWith('0x') ? keyHash.slice(2) : keyHash;\n if (cleanHash.length !== 64) {\n throw new Error(\n `deriveSmartAccountId: keyHash must be 32 bytes (64 hex chars), got ${cleanHash.length}`,\n );\n }\n\n const cleanSalt = salt\n ? (salt.startsWith('0x') ? salt.slice(2) : salt)\n : '0'.repeat(64);\n if (cleanSalt.length !== 64) {\n throw new Error(\n `deriveSmartAccountId: salt must be 32 bytes (64 hex chars), got ${cleanSalt.length}`,\n );\n }\n\n const encoder = new TextEncoder();\n const passphraseBytes = encoder.encode(networkPassphrase);\n const keyHashBytes = hexToBytes(cleanHash);\n const saltBytes = hexToBytes(cleanSalt);\n\n const buffer = new Uint8Array(\n passphraseBytes.length + keyHashBytes.length + saltBytes.length,\n );\n buffer.set(passphraseBytes, 0);\n buffer.set(keyHashBytes, passphraseBytes.length);\n buffer.set(saltBytes, passphraseBytes.length + keyHashBytes.length);\n\n const digest = sha256(buffer);\n return '0x' + bytesToHex(digest);\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n","/**\n * Veridex Protocol SDK — Stellar-Wallets-Kit ModuleInterface implementation\n *\n * Drop-in module for `@creit.tech/stellar-wallets-kit` that exposes\n * Veridex's passkey-backed Soroban smart account as a wallet option.\n *\n * Usage (downstream app):\n * ```ts\n * import { StellarWalletsKit, allowAllModules } from '@creit.tech/stellar-wallets-kit';\n * import { PasskeyManager } from '@veridex/sdk/passkey';\n * import { VeridexStellarWalletModule } from '@veridex/sdk/chains/stellar';\n *\n * const passkey = new PasskeyManager({ rpName: 'My Dapp' });\n * const veridexModule = new VeridexStellarWalletModule({ passkey });\n *\n * const kit = new StellarWalletsKit({\n * network: WalletNetwork.TESTNET,\n * selectedWalletId: VERIDEX_PASSKEY_ID,\n * modules: [...allowAllModules(), veridexModule],\n * });\n * ```\n */\n\nimport { browserSupportsWebAuthn } from '@simplewebauthn/browser';\nimport { PasskeyManager } from '../../core/PasskeyManager.js';\nimport type { PasskeyCredential } from '../../core/PasskeyManager.js';\nimport { StellarPasskeySigner } from './StellarPasskeySigner.js';\nimport {\n StellarModuleType,\n StellarNetworks,\n type StellarWalletModuleInterface,\n type VeridexStellarConfig,\n} from './types.js';\n\nexport const VERIDEX_PASSKEY_ID = 'veridex-passkey';\n\nexport interface VeridexStellarWalletModuleOptions {\n passkey: PasskeyManager;\n credential?: PasskeyCredential;\n config?: VeridexStellarConfig;\n productName?: string;\n productUrl?: string;\n productIcon?: string;\n}\n\nexport class VeridexStellarWalletModule implements StellarWalletModuleInterface {\n readonly moduleType: StellarModuleType = StellarModuleType.HOT_WALLET;\n readonly productId: string = VERIDEX_PASSKEY_ID;\n readonly productName: string;\n readonly productUrl: string;\n readonly productIcon: string;\n\n private readonly signer: StellarPasskeySigner;\n\n constructor(opts: VeridexStellarWalletModuleOptions) {\n this.signer = new StellarPasskeySigner({\n passkey: opts.passkey,\n credential: opts.credential,\n config: opts.config,\n });\n this.productName = opts.productName ?? 'Veridex Passkey';\n this.productUrl = opts.productUrl ?? 'https://veridex.network';\n this.productIcon =\n opts.productIcon ??\n 'https://veridex.network/icons/passkey-256.png';\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n return browserSupportsWebAuthn();\n } catch {\n return false;\n }\n }\n\n async isPlatformWrapper(): Promise<boolean> {\n return false;\n }\n\n async getAddress(params?: {\n path?: string;\n skipRequestAccess?: boolean;\n }): Promise<{ address: string }> {\n return this.signer.getAddress(params?.skipRequestAccess);\n }\n\n async signTransaction(\n xdr: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedTxXdr: string; signerAddress?: string }> {\n return this.signer.signTransaction(xdr, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n\n async signAuthEntry(\n authEntry: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedAuthEntry: string; signerAddress?: string }> {\n return this.signer.signAuthEntry(authEntry, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n\n async signMessage(\n message: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedMessage: string; signerAddress?: string }> {\n return this.signer.signMessage(message, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n}\n\nexport { StellarNetworks };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACyBA,IAAAA,iBAAuB;;;ACrBvB,oBAAuB;AAsBhB,SAAS,gBAAgB,KAAyB;AACvD,QAAM,SAAS,IAAI,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG;AACvD,QAAM,SAAS,SAAS,IAAI,QAAQ,IAAK,OAAO,SAAS,KAAM,CAAC;AAEhE,QAAM,SAAS,KAAK,MAAM;AAC1B,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,SAAO;AACT;;;ACtBO,IAAK,kBAAL,kBAAKC,qBAAL;AACH,EAAAA,iBAAA,YAAS;AACT,EAAAA,iBAAA,aAAU;AACV,EAAAA,iBAAA,eAAY;AACZ,EAAAA,iBAAA,aAAU;AACV,EAAAA,iBAAA,gBAAa;AALL,SAAAA;AAAA,GAAA;AAQL,IAAK,oBAAL,kBAAKC,uBAAL;AACH,EAAAA,mBAAA,eAAY;AACZ,EAAAA,mBAAA,gBAAa;AACb,EAAAA,mBAAA,mBAAgB;AAChB,EAAAA,mBAAA,sBAAmB;AAJX,SAAAA;AAAA,GAAA;;;ACRZ,oBAAuB;AAiBhB,SAAS,qBACZ,SACA,mBACA,MACM;AACN,QAAM,YAAY,QAAQ,WAAW,IAAI,IAAI,QAAQ,MAAM,CAAC,IAAI;AAChE,MAAI,UAAU,WAAW,IAAI;AACzB,UAAM,IAAI;AAAA,MACN,sEAAsE,UAAU,MAAM;AAAA,IAC1F;AAAA,EACJ;AAEA,QAAM,YAAY,OACX,KAAK,WAAW,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI,OACzC,IAAI,OAAO,EAAE;AACnB,MAAI,UAAU,WAAW,IAAI;AACzB,UAAM,IAAI;AAAA,MACN,mEAAmE,UAAU,MAAM;AAAA,IACvF;AAAA,EACJ;AAEA,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,kBAAkB,QAAQ,OAAO,iBAAiB;AACxD,QAAM,eAAe,WAAW,SAAS;AACzC,QAAM,YAAY,WAAW,SAAS;AAEtC,QAAM,SAAS,IAAI;AAAA,IACf,gBAAgB,SAAS,aAAa,SAAS,UAAU;AAAA,EAC7D;AACA,SAAO,IAAI,iBAAiB,CAAC;AAC7B,SAAO,IAAI,cAAc,gBAAgB,MAAM;AAC/C,SAAO,IAAI,WAAW,gBAAgB,SAAS,aAAa,MAAM;AAElE,QAAM,aAAS,sBAAO,MAAM;AAC5B,SAAO,OAAO,WAAW,MAAM;AACnC;AAEA,SAAS,WAAW,KAAyB;AACzC,QAAM,MAAM,IAAI,WAAW,IAAI,SAAS,CAAC;AACzC,WAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,QAAI,CAAC,IAAI,SAAS,IAAI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE;AAAA,EACrD;AACA,SAAO;AACX;AAEA,SAAS,WAAW,OAA2B;AAC3C,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,WAAO,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG;AAAA,EAChD;AACA,SAAO;AACX;;;AHxCO,IAAM,uBAAN,MAA2B;AAAA,EACb;AAAA,EACT;AAAA,EACS;AAAA,EACA;AAAA,EAEjB,YAAY,MAAmC;AAC3C,SAAK,UAAU,KAAK;AACpB,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,KAAK,QAAQ;AAC5B,SAAK,yBAAyB,KAAK,QAAQ;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,WAAW,oBAAoB,OAAqC;AACtE,QAAI,KAAK,wBAAwB;AAC7B,aAAO,EAAE,SAAS,KAAK,uBAAuB;AAAA,IAClD;AACA,UAAM,OAAO,MAAM,KAAK,iBAAiB,iBAAiB;AAC1D,UAAM,KAAK,qBAAqB,KAAK,SAAS,KAAK,OAAO;AAC1D,WAAO,EAAE,SAAS,GAAG;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,gBACF,KACA,MACuD;AACvD,UAAM,OAAO,MAAM,KAAK,iBAAiB,IAAI;AAC7C,UAAM,aAAa,MAAM,qBAAqB,KAAK;AACnD,UAAM,YAAY,KAAK,mBAAmB,KAAK,UAAU;AACzD,UAAM,YAAY,MAAM,KAAK,cAAc,WAAW,IAAI;AAC1D,UAAM,YAAY,KAAK,yBAAyB,MAAM,KAAK,SAAS;AACpE,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,WAAW,IAAI;AAC9C,WAAO,EAAE,aAAa,WAAW,eAAe,MAAM,WAAW,QAAQ;AAAA,EAC7E;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,cACF,WACA,MAC2D;AAC3D,UAAM,OAAO,MAAM,KAAK,iBAAiB,IAAI;AAC7C,UAAM,aAAa,MAAM,qBAAqB,KAAK;AACnD,UAAM,YAAY,KAAK,cAAc,WAAW,UAAU;AAC1D,UAAM,YAAY,MAAM,KAAK,cAAc,WAAW,IAAI;AAC1D,UAAM,YAAY,KAAK,yBAAyB,QAAQ,WAAW,SAAS;AAC5E,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,WAAW,IAAI;AAC9C,WAAO,EAAE,iBAAiB,WAAW,eAAe,MAAM,WAAW,QAAQ;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,YACF,SACA,MACyD;AACzD,UAAM,OAAO,MAAM,KAAK,iBAAiB,IAAI;AAC7C,UAAM,gBAAY,uBAAO,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AAC1D,UAAM,YAAY,MAAM,KAAK,cAAc,WAAW,IAAI;AAC1D,UAAM,YAAY,KAAK,yBAAyB,OAAO,SAAS,SAAS;AACzE,UAAM,EAAE,QAAQ,IAAI,MAAM,KAAK,WAAW,IAAI;AAC9C,WAAO,EAAE,eAAe,WAAW,eAAe,MAAM,WAAW,QAAQ;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA,EAMU,mBAAmB,KAAa,mBAAuC;AAC7E,UAAM,qBAAiB,uBAAO,IAAI,YAAY,EAAE,OAAO,iBAAiB,CAAC;AACzE,UAAM,WAAW,KAAK,aAAa,GAAG;AACtC,UAAM,MAAM,IAAI,WAAW,eAAe,SAAS,SAAS,MAAM;AAClE,QAAI,IAAI,gBAAgB,CAAC;AACzB,QAAI,IAAI,UAAU,eAAe,MAAM;AACvC,eAAO,uBAAO,GAAG;AAAA,EACrB;AAAA,EAEU,cAAc,WAAmB,mBAAuC;AAC9E,WAAO,KAAK,mBAAmB,WAAW,iBAAiB;AAAA,EAC/D;AAAA,EAEA,MAAc,cACV,WACA,YAC6B;AAC7B,UAAM,MAAM,MAAM,KAAK,QAAQ,KAAK,SAAS;AAC7C,WAAO;AAAA,MACH,SAAS,WAAW;AAAA,MACpB,mBAAmB,IAAI;AAAA,MACvB,gBAAgB,IAAI;AAAA,MACpB,gBAAgB,IAAI;AAAA,MACpB,WAAW,IAAI;AAAA,MACf,YAAY,OAAO,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,MACtD,YAAY,OAAO,IAAI,EAAE,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAAA,IAC1D;AAAA,EACJ;AAAA,EAEA,MAAc,iBAAiB,mBAAwD;AACnF,QAAI,KAAK,WAAY,QAAO,KAAK;AACjC,QAAI,mBAAmB;AACnB,YAAM,IAAI;AAAA,QACN;AAAA,MAEJ;AAAA,IACJ;AACA,UAAM,EAAE,WAAW,IAAI,MAAM,KAAK,QAAQ,aAAa;AACvD,SAAK,aAAa;AAClB,WAAO;AAAA,EACX;AAAA,EAEQ,yBACJ,MACA,SACA,WACM;AACN,UAAM,YAAY;AAAA,MACd,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACJ;AACA,UAAM,OAAO,KAAK,UAAU,SAAS;AACrC,QAAI,OAAO,WAAW,aAAa;AAC/B,aAAO,OAAO,KAAK,MAAM,MAAM,EAAE,SAAS,QAAQ;AAAA,IACtD;AAEA,WAAO,KAAK,SAAS,mBAAmB,IAAI,CAAC,CAAC;AAAA,EAClD;AAAA,EAEQ,aAAa,OAA2B;AAC5C,QAAI;AACA,UAAI,OAAO,WAAW,aAAa;AAC/B,eAAO,IAAI,WAAW,OAAO,KAAK,OAAO,QAAQ,CAAC;AAAA,MACtD;AACA,YAAM,SAAS,KAAK,KAAK;AACzB,YAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,eAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,IAAK,OAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AACtE,aAAO;AAAA,IACX,QAAQ;AAEJ,aAAO,gBAAgB,KAAK;AAAA,IAChC;AAAA,EACJ;AACJ;;;AIlLA,qBAAwC;AAWjC,IAAM,qBAAqB;AAW3B,IAAM,6BAAN,MAAyE;AAAA,EACnE;AAAA,EACA,YAAoB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EAEQ;AAAA,EAEjB,YAAY,MAAyC;AACjD,SAAK,SAAS,IAAI,qBAAqB;AAAA,MACnC,SAAS,KAAK;AAAA,MACd,YAAY,KAAK;AAAA,MACjB,QAAQ,KAAK;AAAA,IACjB,CAAC;AACD,SAAK,cAAc,KAAK,eAAe;AACvC,SAAK,aAAa,KAAK,cAAc;AACrC,SAAK,cACD,KAAK,eACL;AAAA,EACR;AAAA,EAEA,MAAM,cAAgC;AAClC,QAAI;AACA,iBAAO,wCAAwB;AAAA,IACnC,QAAQ;AACJ,aAAO;AAAA,IACX;AAAA,EACJ;AAAA,EAEA,MAAM,oBAAsC;AACxC,WAAO;AAAA,EACX;AAAA,EAEA,MAAM,WAAW,QAGgB;AAC7B,WAAO,KAAK,OAAO,WAAW,QAAQ,iBAAiB;AAAA,EAC3D;AAAA,EAEA,MAAM,gBACF,KACA,MACwD;AACxD,WAAO,KAAK,OAAO,gBAAgB,KAAK;AAAA,MACpC,mBAAmB,MAAM;AAAA,MACzB,SAAS,MAAM;AAAA,IACnB,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,cACF,WACA,MAC4D;AAC5D,WAAO,KAAK,OAAO,cAAc,WAAW;AAAA,MACxC,mBAAmB,MAAM;AAAA,MACzB,SAAS,MAAM;AAAA,IACnB,CAAC;AAAA,EACL;AAAA,EAEA,MAAM,YACF,SACA,MAC0D;AAC1D,WAAO,KAAK,OAAO,YAAY,SAAS;AAAA,MACpC,mBAAmB,MAAM;AAAA,MACzB,SAAS,MAAM;AAAA,IACnB,CAAC;AAAA,EACL;AACJ;","names":["import_sha256","StellarNetworks","StellarModuleType"]}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import {
|
|
2
|
+
base64URLDecode
|
|
3
|
+
} from "../../chunk-EFIXFA6V.mjs";
|
|
4
|
+
import "../../chunk-RD6ZYUVG.mjs";
|
|
5
|
+
|
|
6
|
+
// src/chains/stellar/StellarPasskeySigner.ts
|
|
7
|
+
import { sha256 as sha2562 } from "@noble/hashes/sha256";
|
|
8
|
+
|
|
9
|
+
// src/chains/stellar/types.ts
|
|
10
|
+
var StellarNetworks = /* @__PURE__ */ ((StellarNetworks2) => {
|
|
11
|
+
StellarNetworks2["PUBLIC"] = "Public Global Stellar Network ; September 2015";
|
|
12
|
+
StellarNetworks2["TESTNET"] = "Test SDF Network ; September 2015";
|
|
13
|
+
StellarNetworks2["FUTURENET"] = "Test SDF Future Network ; October 2022";
|
|
14
|
+
StellarNetworks2["SANDBOX"] = "Local Sandbox Stellar Network ; September 2022";
|
|
15
|
+
StellarNetworks2["STANDALONE"] = "Standalone Network ; February 2017";
|
|
16
|
+
return StellarNetworks2;
|
|
17
|
+
})(StellarNetworks || {});
|
|
18
|
+
var StellarModuleType = /* @__PURE__ */ ((StellarModuleType2) => {
|
|
19
|
+
StellarModuleType2["HW_WALLET"] = "HW_WALLET";
|
|
20
|
+
StellarModuleType2["HOT_WALLET"] = "HOT_WALLET";
|
|
21
|
+
StellarModuleType2["BRIDGE_WALLET"] = "BRIDGE_WALLET";
|
|
22
|
+
StellarModuleType2["AIR_GAPED_WALLET"] = "AIR_GAPED_WALLET";
|
|
23
|
+
return StellarModuleType2;
|
|
24
|
+
})(StellarModuleType || {});
|
|
25
|
+
|
|
26
|
+
// src/chains/stellar/SmartAccount.ts
|
|
27
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
28
|
+
function deriveSmartAccountId(keyHash, networkPassphrase, salt) {
|
|
29
|
+
const cleanHash = keyHash.startsWith("0x") ? keyHash.slice(2) : keyHash;
|
|
30
|
+
if (cleanHash.length !== 64) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`deriveSmartAccountId: keyHash must be 32 bytes (64 hex chars), got ${cleanHash.length}`
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
const cleanSalt = salt ? salt.startsWith("0x") ? salt.slice(2) : salt : "0".repeat(64);
|
|
36
|
+
if (cleanSalt.length !== 64) {
|
|
37
|
+
throw new Error(
|
|
38
|
+
`deriveSmartAccountId: salt must be 32 bytes (64 hex chars), got ${cleanSalt.length}`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const encoder = new TextEncoder();
|
|
42
|
+
const passphraseBytes = encoder.encode(networkPassphrase);
|
|
43
|
+
const keyHashBytes = hexToBytes(cleanHash);
|
|
44
|
+
const saltBytes = hexToBytes(cleanSalt);
|
|
45
|
+
const buffer = new Uint8Array(
|
|
46
|
+
passphraseBytes.length + keyHashBytes.length + saltBytes.length
|
|
47
|
+
);
|
|
48
|
+
buffer.set(passphraseBytes, 0);
|
|
49
|
+
buffer.set(keyHashBytes, passphraseBytes.length);
|
|
50
|
+
buffer.set(saltBytes, passphraseBytes.length + keyHashBytes.length);
|
|
51
|
+
const digest = sha256(buffer);
|
|
52
|
+
return "0x" + bytesToHex(digest);
|
|
53
|
+
}
|
|
54
|
+
function hexToBytes(hex) {
|
|
55
|
+
const out = new Uint8Array(hex.length / 2);
|
|
56
|
+
for (let i = 0; i < out.length; i++) {
|
|
57
|
+
out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
function bytesToHex(bytes) {
|
|
62
|
+
let hex = "";
|
|
63
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
64
|
+
hex += bytes[i].toString(16).padStart(2, "0");
|
|
65
|
+
}
|
|
66
|
+
return hex;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// src/chains/stellar/StellarPasskeySigner.ts
|
|
70
|
+
var StellarPasskeySigner = class {
|
|
71
|
+
passkey;
|
|
72
|
+
credential;
|
|
73
|
+
network;
|
|
74
|
+
smartAccountContractId;
|
|
75
|
+
constructor(opts) {
|
|
76
|
+
this.passkey = opts.passkey;
|
|
77
|
+
this.credential = opts.credential;
|
|
78
|
+
this.network = opts.config?.network ?? "Test SDF Network ; September 2015" /* TESTNET */;
|
|
79
|
+
this.smartAccountContractId = opts.config?.smartAccountContractId;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns the Soroban smart-account address (C-address-derivable hex)
|
|
83
|
+
* associated with the active passkey. If a fixed contract id was
|
|
84
|
+
* configured we return it verbatim; otherwise we derive deterministically.
|
|
85
|
+
*/
|
|
86
|
+
async getAddress(skipRequestAccess = false) {
|
|
87
|
+
if (this.smartAccountContractId) {
|
|
88
|
+
return { address: this.smartAccountContractId };
|
|
89
|
+
}
|
|
90
|
+
const cred = await this.ensureCredential(skipRequestAccess);
|
|
91
|
+
const id = deriveSmartAccountId(cred.keyHash, this.network);
|
|
92
|
+
return { address: id };
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Produce a SEP-43 `signedTxXdr` for the given transaction envelope XDR.
|
|
96
|
+
*
|
|
97
|
+
* Because we do not bundle `@stellar/stellar-sdk` we hash the XDR's
|
|
98
|
+
* binary form prefixed with the network passphrase. Consumers that need
|
|
99
|
+
* canonical Stellar transaction hashes should preprocess `xdr` to the
|
|
100
|
+
* spec-compliant preimage before calling, or override this method.
|
|
101
|
+
*/
|
|
102
|
+
async signTransaction(xdr, opts) {
|
|
103
|
+
const cred = await this.ensureCredential(true);
|
|
104
|
+
const passphrase = opts?.networkPassphrase ?? this.network;
|
|
105
|
+
const challenge = this.hashTransactionXdr(xdr, passphrase);
|
|
106
|
+
const assertion = await this.signChallenge(challenge, cred);
|
|
107
|
+
const container = this.encodeAssertionContainer("tx", xdr, assertion);
|
|
108
|
+
const { address } = await this.getAddress(true);
|
|
109
|
+
return { signedTxXdr: container, signerAddress: opts?.address ?? address };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Sign a Soroban `HashIdPreimageSorobanAuthorization` XDR. The auth
|
|
113
|
+
* entry payload is hashed and wrapped identically to a transaction.
|
|
114
|
+
*/
|
|
115
|
+
async signAuthEntry(authEntry, opts) {
|
|
116
|
+
const cred = await this.ensureCredential(true);
|
|
117
|
+
const passphrase = opts?.networkPassphrase ?? this.network;
|
|
118
|
+
const challenge = this.hashAuthEntry(authEntry, passphrase);
|
|
119
|
+
const assertion = await this.signChallenge(challenge, cred);
|
|
120
|
+
const container = this.encodeAssertionContainer("auth", authEntry, assertion);
|
|
121
|
+
const { address } = await this.getAddress(true);
|
|
122
|
+
return { signedAuthEntry: container, signerAddress: opts?.address ?? address };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Sign an arbitrary message per SEP-43 `signMessage`.
|
|
126
|
+
*/
|
|
127
|
+
async signMessage(message, opts) {
|
|
128
|
+
const cred = await this.ensureCredential(true);
|
|
129
|
+
const challenge = sha2562(new TextEncoder().encode(message));
|
|
130
|
+
const assertion = await this.signChallenge(challenge, cred);
|
|
131
|
+
const container = this.encodeAssertionContainer("msg", message, assertion);
|
|
132
|
+
const { address } = await this.getAddress(true);
|
|
133
|
+
return { signedMessage: container, signerAddress: opts?.address ?? address };
|
|
134
|
+
}
|
|
135
|
+
// ------------------------------------------------------------------
|
|
136
|
+
// Internals
|
|
137
|
+
// ------------------------------------------------------------------
|
|
138
|
+
hashTransactionXdr(xdr, networkPassphrase) {
|
|
139
|
+
const passphraseHash = sha2562(new TextEncoder().encode(networkPassphrase));
|
|
140
|
+
const xdrBytes = this.decodeBase64(xdr);
|
|
141
|
+
const buf = new Uint8Array(passphraseHash.length + xdrBytes.length);
|
|
142
|
+
buf.set(passphraseHash, 0);
|
|
143
|
+
buf.set(xdrBytes, passphraseHash.length);
|
|
144
|
+
return sha2562(buf);
|
|
145
|
+
}
|
|
146
|
+
hashAuthEntry(authEntry, networkPassphrase) {
|
|
147
|
+
return this.hashTransactionXdr(authEntry, networkPassphrase);
|
|
148
|
+
}
|
|
149
|
+
async signChallenge(challenge, credential) {
|
|
150
|
+
const sig = await this.passkey.sign(challenge);
|
|
151
|
+
return {
|
|
152
|
+
keyHash: credential.keyHash,
|
|
153
|
+
authenticatorData: sig.authenticatorData,
|
|
154
|
+
clientDataJSON: sig.clientDataJSON,
|
|
155
|
+
challengeIndex: sig.challengeIndex,
|
|
156
|
+
typeIndex: sig.typeIndex,
|
|
157
|
+
signatureR: "0x" + sig.r.toString(16).padStart(64, "0"),
|
|
158
|
+
signatureS: "0x" + sig.s.toString(16).padStart(64, "0")
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async ensureCredential(skipRequestAccess) {
|
|
162
|
+
if (this.credential) return this.credential;
|
|
163
|
+
if (skipRequestAccess) {
|
|
164
|
+
throw new Error(
|
|
165
|
+
"StellarPasskeySigner: no credential cached. Call passkey.authenticate() first or pass `credential` to the constructor."
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const { credential } = await this.passkey.authenticate();
|
|
169
|
+
this.credential = credential;
|
|
170
|
+
return credential;
|
|
171
|
+
}
|
|
172
|
+
encodeAssertionContainer(kind, payload, assertion) {
|
|
173
|
+
const container = {
|
|
174
|
+
v: 1,
|
|
175
|
+
kind,
|
|
176
|
+
payload,
|
|
177
|
+
assertion
|
|
178
|
+
};
|
|
179
|
+
const json = JSON.stringify(container);
|
|
180
|
+
if (typeof Buffer !== "undefined") {
|
|
181
|
+
return Buffer.from(json, "utf8").toString("base64");
|
|
182
|
+
}
|
|
183
|
+
return btoa(unescape(encodeURIComponent(json)));
|
|
184
|
+
}
|
|
185
|
+
decodeBase64(input) {
|
|
186
|
+
try {
|
|
187
|
+
if (typeof Buffer !== "undefined") {
|
|
188
|
+
return new Uint8Array(Buffer.from(input, "base64"));
|
|
189
|
+
}
|
|
190
|
+
const binary = atob(input);
|
|
191
|
+
const bytes = new Uint8Array(binary.length);
|
|
192
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
193
|
+
return bytes;
|
|
194
|
+
} catch {
|
|
195
|
+
return base64URLDecode(input);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
// src/chains/stellar/VeridexStellarWalletModule.ts
|
|
201
|
+
import { browserSupportsWebAuthn } from "@simplewebauthn/browser";
|
|
202
|
+
var VERIDEX_PASSKEY_ID = "veridex-passkey";
|
|
203
|
+
var VeridexStellarWalletModule = class {
|
|
204
|
+
moduleType = "HOT_WALLET" /* HOT_WALLET */;
|
|
205
|
+
productId = VERIDEX_PASSKEY_ID;
|
|
206
|
+
productName;
|
|
207
|
+
productUrl;
|
|
208
|
+
productIcon;
|
|
209
|
+
signer;
|
|
210
|
+
constructor(opts) {
|
|
211
|
+
this.signer = new StellarPasskeySigner({
|
|
212
|
+
passkey: opts.passkey,
|
|
213
|
+
credential: opts.credential,
|
|
214
|
+
config: opts.config
|
|
215
|
+
});
|
|
216
|
+
this.productName = opts.productName ?? "Veridex Passkey";
|
|
217
|
+
this.productUrl = opts.productUrl ?? "https://veridex.network";
|
|
218
|
+
this.productIcon = opts.productIcon ?? "https://veridex.network/icons/passkey-256.png";
|
|
219
|
+
}
|
|
220
|
+
async isAvailable() {
|
|
221
|
+
try {
|
|
222
|
+
return browserSupportsWebAuthn();
|
|
223
|
+
} catch {
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
async isPlatformWrapper() {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
async getAddress(params) {
|
|
231
|
+
return this.signer.getAddress(params?.skipRequestAccess);
|
|
232
|
+
}
|
|
233
|
+
async signTransaction(xdr, opts) {
|
|
234
|
+
return this.signer.signTransaction(xdr, {
|
|
235
|
+
networkPassphrase: opts?.networkPassphrase,
|
|
236
|
+
address: opts?.address
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
async signAuthEntry(authEntry, opts) {
|
|
240
|
+
return this.signer.signAuthEntry(authEntry, {
|
|
241
|
+
networkPassphrase: opts?.networkPassphrase,
|
|
242
|
+
address: opts?.address
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
async signMessage(message, opts) {
|
|
246
|
+
return this.signer.signMessage(message, {
|
|
247
|
+
networkPassphrase: opts?.networkPassphrase,
|
|
248
|
+
address: opts?.address
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
export {
|
|
253
|
+
StellarModuleType,
|
|
254
|
+
StellarNetworks,
|
|
255
|
+
StellarPasskeySigner,
|
|
256
|
+
VERIDEX_PASSKEY_ID,
|
|
257
|
+
VeridexStellarWalletModule,
|
|
258
|
+
deriveSmartAccountId
|
|
259
|
+
};
|
|
260
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/chains/stellar/StellarPasskeySigner.ts","../../../src/chains/stellar/types.ts","../../../src/chains/stellar/SmartAccount.ts","../../../src/chains/stellar/VeridexStellarWalletModule.ts"],"sourcesContent":["/**\n * Veridex Protocol SDK — Stellar Passkey Signer\n *\n * Bridges Veridex's WebAuthn `PasskeyManager` to the SEP-43 signing surface\n * expected by Soroban smart accounts (and the Stellar-Wallets-Kit\n * `ModuleInterface`).\n *\n * Design:\n * - The signer treats every SEP-43 signing call (transaction / auth entry\n * / message) as a request to produce a WebAuthn assertion over the\n * SHA-256 of a canonical preimage.\n * - For a transaction we hash `network_id || tagged_tx_envelope` per the\n * XDR-hash spec; for an auth entry we hash the\n * `HashIdPreimageSorobanAuthorization`; for a message we hash the bytes\n * directly.\n * - The returned `signedTxXdr` / `signedAuthEntry` strings are\n * base64-encoded JSON containers carrying the assertion. The downstream\n * Soroban smart-account contract (`__check_auth`) is responsible for\n * parsing the container, verifying secp256r1, and authorizing.\n *\n * This separation lets `@veridex/sdk` ship without a hard dependency on\n * `@stellar/stellar-sdk`. Consumers who want full XDR-aware signing can\n * subclass and override `hashTransactionXdr` / `hashAuthEntry`.\n */\n\nimport { sha256 } from '@noble/hashes/sha256';\nimport { PasskeyManager } from '../../core/PasskeyManager.js';\nimport type { PasskeyCredential } from '../../core/PasskeyManager.js';\nimport { base64URLDecode } from '../../utils.js';\nimport {\n StellarNetworks,\n type PasskeyAuthAssertion,\n type VeridexStellarConfig,\n} from './types.js';\nimport { deriveSmartAccountId } from './SmartAccount.js';\n\nexport interface StellarPasskeySignerOptions {\n passkey: PasskeyManager;\n credential?: PasskeyCredential;\n config?: VeridexStellarConfig;\n}\n\nexport class StellarPasskeySigner {\n private readonly passkey: PasskeyManager;\n private credential?: PasskeyCredential;\n private readonly network: StellarNetworks;\n private readonly smartAccountContractId?: string;\n\n constructor(opts: StellarPasskeySignerOptions) {\n this.passkey = opts.passkey;\n this.credential = opts.credential;\n this.network = opts.config?.network ?? StellarNetworks.TESTNET;\n this.smartAccountContractId = opts.config?.smartAccountContractId;\n }\n\n /**\n * Returns the Soroban smart-account address (C-address-derivable hex)\n * associated with the active passkey. If a fixed contract id was\n * configured we return it verbatim; otherwise we derive deterministically.\n */\n async getAddress(skipRequestAccess = false): Promise<{ address: string }> {\n if (this.smartAccountContractId) {\n return { address: this.smartAccountContractId };\n }\n const cred = await this.ensureCredential(skipRequestAccess);\n const id = deriveSmartAccountId(cred.keyHash, this.network);\n return { address: id };\n }\n\n /**\n * Produce a SEP-43 `signedTxXdr` for the given transaction envelope XDR.\n *\n * Because we do not bundle `@stellar/stellar-sdk` we hash the XDR's\n * binary form prefixed with the network passphrase. Consumers that need\n * canonical Stellar transaction hashes should preprocess `xdr` to the\n * spec-compliant preimage before calling, or override this method.\n */\n async signTransaction(\n xdr: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedTxXdr: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const passphrase = opts?.networkPassphrase ?? this.network;\n const challenge = this.hashTransactionXdr(xdr, passphrase);\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('tx', xdr, assertion);\n const { address } = await this.getAddress(true);\n return { signedTxXdr: container, signerAddress: opts?.address ?? address };\n }\n\n /**\n * Sign a Soroban `HashIdPreimageSorobanAuthorization` XDR. The auth\n * entry payload is hashed and wrapped identically to a transaction.\n */\n async signAuthEntry(\n authEntry: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedAuthEntry: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const passphrase = opts?.networkPassphrase ?? this.network;\n const challenge = this.hashAuthEntry(authEntry, passphrase);\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('auth', authEntry, assertion);\n const { address } = await this.getAddress(true);\n return { signedAuthEntry: container, signerAddress: opts?.address ?? address };\n }\n\n /**\n * Sign an arbitrary message per SEP-43 `signMessage`.\n */\n async signMessage(\n message: string,\n opts?: { networkPassphrase?: string; address?: string },\n ): Promise<{ signedMessage: string; signerAddress: string }> {\n const cred = await this.ensureCredential(true);\n const challenge = sha256(new TextEncoder().encode(message));\n const assertion = await this.signChallenge(challenge, cred);\n const container = this.encodeAssertionContainer('msg', message, assertion);\n const { address } = await this.getAddress(true);\n return { signedMessage: container, signerAddress: opts?.address ?? address };\n }\n\n // ------------------------------------------------------------------\n // Internals\n // ------------------------------------------------------------------\n\n protected hashTransactionXdr(xdr: string, networkPassphrase: string): Uint8Array {\n const passphraseHash = sha256(new TextEncoder().encode(networkPassphrase));\n const xdrBytes = this.decodeBase64(xdr);\n const buf = new Uint8Array(passphraseHash.length + xdrBytes.length);\n buf.set(passphraseHash, 0);\n buf.set(xdrBytes, passphraseHash.length);\n return sha256(buf);\n }\n\n protected hashAuthEntry(authEntry: string, networkPassphrase: string): Uint8Array {\n return this.hashTransactionXdr(authEntry, networkPassphrase);\n }\n\n private async signChallenge(\n challenge: Uint8Array,\n credential: PasskeyCredential,\n ): Promise<PasskeyAuthAssertion> {\n const sig = await this.passkey.sign(challenge);\n return {\n keyHash: credential.keyHash,\n authenticatorData: sig.authenticatorData,\n clientDataJSON: sig.clientDataJSON,\n challengeIndex: sig.challengeIndex,\n typeIndex: sig.typeIndex,\n signatureR: '0x' + sig.r.toString(16).padStart(64, '0'),\n signatureS: '0x' + sig.s.toString(16).padStart(64, '0'),\n };\n }\n\n private async ensureCredential(skipRequestAccess: boolean): Promise<PasskeyCredential> {\n if (this.credential) return this.credential;\n if (skipRequestAccess) {\n throw new Error(\n 'StellarPasskeySigner: no credential cached. Call passkey.authenticate() ' +\n 'first or pass `credential` to the constructor.',\n );\n }\n const { credential } = await this.passkey.authenticate();\n this.credential = credential;\n return credential;\n }\n\n private encodeAssertionContainer(\n kind: 'tx' | 'auth' | 'msg',\n payload: string,\n assertion: PasskeyAuthAssertion,\n ): string {\n const container = {\n v: 1,\n kind,\n payload,\n assertion,\n };\n const json = JSON.stringify(container);\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(json, 'utf8').toString('base64');\n }\n // Browser fallback.\n return btoa(unescape(encodeURIComponent(json)));\n }\n\n private decodeBase64(input: string): Uint8Array {\n try {\n if (typeof Buffer !== 'undefined') {\n return new Uint8Array(Buffer.from(input, 'base64'));\n }\n const binary = atob(input);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n } catch {\n // Fall back to base64url if standard base64 fails.\n return base64URLDecode(input);\n }\n }\n}\n","/**\n * Veridex Protocol SDK — Stellar chain types\n *\n * Local mirror of the subset of the Stellar-Wallets-Kit `ModuleInterface`\n * contract we implement. We mirror it (rather than importing from\n * `@creit.tech/stellar-wallets-kit`) so `@veridex/sdk` does not gain a hard\n * peer dependency on the kit. Consumers who already depend on the kit can\n * cast our module to the upstream type — the shapes are structurally\n * identical.\n *\n * Upstream reference: `@creit.tech/stellar-wallets-kit` →\n * src/types/mod.ts → `ModuleInterface`\n */\n\nexport enum StellarNetworks {\n PUBLIC = 'Public Global Stellar Network ; September 2015',\n TESTNET = 'Test SDF Network ; September 2015',\n FUTURENET = 'Test SDF Future Network ; October 2022',\n SANDBOX = 'Local Sandbox Stellar Network ; September 2022',\n STANDALONE = 'Standalone Network ; February 2017',\n}\n\nexport enum StellarModuleType {\n HW_WALLET = 'HW_WALLET',\n HOT_WALLET = 'HOT_WALLET',\n BRIDGE_WALLET = 'BRIDGE_WALLET',\n AIR_GAPED_WALLET = 'AIR_GAPED_WALLET',\n}\n\nexport interface StellarKitError {\n code: number;\n message: string;\n ext?: string;\n}\n\n/**\n * Stellar-Wallets-Kit `ModuleInterface` mirror.\n * Only the methods we implement are documented; signature-compatible with\n * the upstream contract.\n */\nexport interface StellarWalletModuleInterface {\n moduleType: StellarModuleType;\n productId: string;\n productName: string;\n productUrl: string;\n productIcon: string;\n\n isAvailable(): Promise<boolean>;\n isPlatformWrapper?(): Promise<boolean>;\n\n getAddress(params?: {\n path?: string;\n skipRequestAccess?: boolean;\n }): Promise<{ address: string }>;\n\n signTransaction(\n xdr: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedTxXdr: string; signerAddress?: string }>;\n\n signAuthEntry(\n authEntry: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedAuthEntry: string; signerAddress?: string }>;\n\n signMessage(\n message: string,\n opts?: {\n networkPassphrase?: string;\n address?: string;\n path?: string;\n },\n ): Promise<{ signedMessage: string; signerAddress?: string }>;\n}\n\n/**\n * Veridex-specific configuration for the Stellar passkey signer.\n */\nexport interface VeridexStellarConfig {\n /** Stellar network passphrase. Defaults to TESTNET. */\n network?: StellarNetworks;\n /**\n * Soroban RPC URL (used to resolve the smart-account address or submit\n * transactions when `signAndSubmitTransaction` is invoked).\n */\n rpcUrl?: string;\n /**\n * Optional pre-deployed smart-account contract id (C-address). If\n * provided, `getAddress()` returns this directly. Otherwise the address\n * is derived deterministically from the passkey `keyHash`.\n */\n smartAccountContractId?: string;\n /**\n * Override the deterministic smart-account factory contract. Used for\n * address derivation when `smartAccountContractId` is not set.\n */\n smartAccountFactory?: string;\n}\n\n/**\n * A signed WebAuthn assertion ready to be embedded in a Soroban auth entry.\n *\n * The shape matches what a Soroban smart-account's `__check_auth` entrypoint\n * needs to verify a secp256r1 passkey signature:\n * - `keyHash` identifies which registered passkey signed\n * - `authenticatorData` + `clientDataJSON` are the WebAuthn assertion\n * - `r`, `s` are the secp256r1 signature components\n */\nexport interface PasskeyAuthAssertion {\n keyHash: string;\n authenticatorData: string;\n clientDataJSON: string;\n challengeIndex: number;\n typeIndex: number;\n signatureR: string;\n signatureS: string;\n}\n","/**\n * Veridex Protocol SDK — Soroban smart-account address derivation\n *\n * The Veridex Stellar adapter binds a WebAuthn passkey to a Soroban smart\n * account whose `__check_auth` entry verifies secp256r1 signatures against\n * the passkey's `keyHash`.\n *\n * For the credibility-artifact stage we expose deterministic address\n * derivation only — actual deployment is handled by a separate Soroban\n * factory contract (see `contracts/stellar/` once added). This keeps the\n * SDK chain-agnostic and avoids pulling in the heavy `@stellar/stellar-sdk`\n * runtime.\n */\n\nimport { sha256 } from '@noble/hashes/sha256';\n\n/**\n * Deterministically derive a Soroban contract id (C-address) from a passkey\n * `keyHash`. This mirrors the SEP-0011 Stellar contract-id derivation\n * scheme: contract_id = sha256(networkPassphrase || keyHash || salt).\n *\n * NOTE: This returns a stable 32-byte identifier encoded as hex. To produce\n * a canonical `C...` strkey representation the consumer must encode it with\n * `StrKey.encodeContract` from `@stellar/stellar-sdk`. We deliberately keep\n * the encoding out of `@veridex/sdk` to avoid a hard dependency.\n *\n * @param keyHash - The Veridex passkey keyHash (hex, with or without 0x).\n * @param networkPassphrase - Stellar network passphrase (e.g. testnet).\n * @param salt - Optional 32-byte salt (hex). Defaults to all-zeros.\n * @returns The 32-byte contract id encoded as a 0x-prefixed hex string.\n */\nexport function deriveSmartAccountId(\n keyHash: string,\n networkPassphrase: string,\n salt?: string,\n): string {\n const cleanHash = keyHash.startsWith('0x') ? keyHash.slice(2) : keyHash;\n if (cleanHash.length !== 64) {\n throw new Error(\n `deriveSmartAccountId: keyHash must be 32 bytes (64 hex chars), got ${cleanHash.length}`,\n );\n }\n\n const cleanSalt = salt\n ? (salt.startsWith('0x') ? salt.slice(2) : salt)\n : '0'.repeat(64);\n if (cleanSalt.length !== 64) {\n throw new Error(\n `deriveSmartAccountId: salt must be 32 bytes (64 hex chars), got ${cleanSalt.length}`,\n );\n }\n\n const encoder = new TextEncoder();\n const passphraseBytes = encoder.encode(networkPassphrase);\n const keyHashBytes = hexToBytes(cleanHash);\n const saltBytes = hexToBytes(cleanSalt);\n\n const buffer = new Uint8Array(\n passphraseBytes.length + keyHashBytes.length + saltBytes.length,\n );\n buffer.set(passphraseBytes, 0);\n buffer.set(keyHashBytes, passphraseBytes.length);\n buffer.set(saltBytes, passphraseBytes.length + keyHashBytes.length);\n\n const digest = sha256(buffer);\n return '0x' + bytesToHex(digest);\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n out[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let hex = '';\n for (let i = 0; i < bytes.length; i++) {\n hex += bytes[i].toString(16).padStart(2, '0');\n }\n return hex;\n}\n","/**\n * Veridex Protocol SDK — Stellar-Wallets-Kit ModuleInterface implementation\n *\n * Drop-in module for `@creit.tech/stellar-wallets-kit` that exposes\n * Veridex's passkey-backed Soroban smart account as a wallet option.\n *\n * Usage (downstream app):\n * ```ts\n * import { StellarWalletsKit, allowAllModules } from '@creit.tech/stellar-wallets-kit';\n * import { PasskeyManager } from '@veridex/sdk/passkey';\n * import { VeridexStellarWalletModule } from '@veridex/sdk/chains/stellar';\n *\n * const passkey = new PasskeyManager({ rpName: 'My Dapp' });\n * const veridexModule = new VeridexStellarWalletModule({ passkey });\n *\n * const kit = new StellarWalletsKit({\n * network: WalletNetwork.TESTNET,\n * selectedWalletId: VERIDEX_PASSKEY_ID,\n * modules: [...allowAllModules(), veridexModule],\n * });\n * ```\n */\n\nimport { browserSupportsWebAuthn } from '@simplewebauthn/browser';\nimport { PasskeyManager } from '../../core/PasskeyManager.js';\nimport type { PasskeyCredential } from '../../core/PasskeyManager.js';\nimport { StellarPasskeySigner } from './StellarPasskeySigner.js';\nimport {\n StellarModuleType,\n StellarNetworks,\n type StellarWalletModuleInterface,\n type VeridexStellarConfig,\n} from './types.js';\n\nexport const VERIDEX_PASSKEY_ID = 'veridex-passkey';\n\nexport interface VeridexStellarWalletModuleOptions {\n passkey: PasskeyManager;\n credential?: PasskeyCredential;\n config?: VeridexStellarConfig;\n productName?: string;\n productUrl?: string;\n productIcon?: string;\n}\n\nexport class VeridexStellarWalletModule implements StellarWalletModuleInterface {\n readonly moduleType: StellarModuleType = StellarModuleType.HOT_WALLET;\n readonly productId: string = VERIDEX_PASSKEY_ID;\n readonly productName: string;\n readonly productUrl: string;\n readonly productIcon: string;\n\n private readonly signer: StellarPasskeySigner;\n\n constructor(opts: VeridexStellarWalletModuleOptions) {\n this.signer = new StellarPasskeySigner({\n passkey: opts.passkey,\n credential: opts.credential,\n config: opts.config,\n });\n this.productName = opts.productName ?? 'Veridex Passkey';\n this.productUrl = opts.productUrl ?? 'https://veridex.network';\n this.productIcon =\n opts.productIcon ??\n 'https://veridex.network/icons/passkey-256.png';\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n return browserSupportsWebAuthn();\n } catch {\n return false;\n }\n }\n\n async isPlatformWrapper(): Promise<boolean> {\n return false;\n }\n\n async getAddress(params?: {\n path?: string;\n skipRequestAccess?: boolean;\n }): Promise<{ address: string }> {\n return this.signer.getAddress(params?.skipRequestAccess);\n }\n\n async signTransaction(\n xdr: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedTxXdr: string; signerAddress?: string }> {\n return this.signer.signTransaction(xdr, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n\n async signAuthEntry(\n authEntry: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedAuthEntry: string; signerAddress?: string }> {\n return this.signer.signAuthEntry(authEntry, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n\n async signMessage(\n message: string,\n opts?: { networkPassphrase?: string; address?: string; path?: string },\n ): Promise<{ signedMessage: string; signerAddress?: string }> {\n return this.signer.signMessage(message, {\n networkPassphrase: opts?.networkPassphrase,\n address: opts?.address,\n });\n }\n}\n\nexport { StellarNetworks };\n"],"mappings":"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","names":["sha256","StellarNetworks","StellarModuleType","sha256"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SuiClient as SuiClient$1 } from '@mysten/sui/client';
|
|
2
|
-
import { a as SessionKey } from '../../types-
|
|
2
|
+
import { a as SessionKey } from '../../types-C564CfsE.mjs';
|
|
3
3
|
import { C as ChainClient, a as ChainConfig, T as TransferParams, E as ExecuteParams, B as BridgeParams, W as WebAuthnSignature, D as DispatchResult, V as VaultCreationResult, x as RegisterSessionParams, y as RevokeSessionParams, S as SessionValidationResult } from '../../types-DP2CQT8p.mjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EVMClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-E5HHE7IW.mjs";
|
|
4
4
|
|
|
5
5
|
// src/chains/avalanche/AvalancheClient.ts
|
|
6
6
|
import { ethers } from "ethers";
|
|
@@ -213,4 +213,4 @@ var AvalancheClient = class extends EVMClient {
|
|
|
213
213
|
export {
|
|
214
214
|
AvalancheClient
|
|
215
215
|
};
|
|
216
|
-
//# sourceMappingURL=chunk-
|
|
216
|
+
//# sourceMappingURL=chunk-6JULIESG.mjs.map
|
|
@@ -20,7 +20,9 @@ var ERC20_ABI = [
|
|
|
20
20
|
var HUB_ABI = [
|
|
21
21
|
"function dispatch(tuple(bytes authenticatorData, string clientDataJSON, uint256 challengeIndex, uint256 typeIndex, uint256 r, uint256 s) signature, uint256 publicKeyX, uint256 publicKeyY, uint16 targetChain, bytes actionPayload, uint256 nonce) payable returns (uint64 sequence)",
|
|
22
22
|
"function userNonces(bytes32 userKeyHash) view returns (uint256)",
|
|
23
|
-
|
|
23
|
+
// Hub exposes the Wormhole core bridge address; message fee is read from the
|
|
24
|
+
// bridge directly (getMessageFee() was removed from the Hub).
|
|
25
|
+
"function wormhole() view returns (address)",
|
|
24
26
|
"function getVaultAddress(bytes32 userKeyHash) view returns (address)",
|
|
25
27
|
"function vaultExists(bytes32 userKeyHash) view returns (bool)",
|
|
26
28
|
"function createVault(bytes32 userKeyHash) returns (address)",
|
|
@@ -77,6 +79,8 @@ var EVMClient = class {
|
|
|
77
79
|
hubContract;
|
|
78
80
|
factoryContract = null;
|
|
79
81
|
cachedImplementation = null;
|
|
82
|
+
cachedWormholeAddress = null;
|
|
83
|
+
cachedMessageFee = null;
|
|
80
84
|
constructor(config) {
|
|
81
85
|
this.config = {
|
|
82
86
|
name: config.name ?? `EVM Chain ${config.chainId}`,
|
|
@@ -249,8 +253,24 @@ var EVMClient = class {
|
|
|
249
253
|
return Number(count);
|
|
250
254
|
}
|
|
251
255
|
async getMessageFee() {
|
|
252
|
-
const
|
|
253
|
-
|
|
256
|
+
const now = Date.now();
|
|
257
|
+
if (this.cachedMessageFee && this.cachedMessageFee.expiresAt > now) {
|
|
258
|
+
return this.cachedMessageFee.value;
|
|
259
|
+
}
|
|
260
|
+
let wormholeAddress = this.config.contracts.wormholeCoreBridge ?? this.cachedWormholeAddress;
|
|
261
|
+
if (!wormholeAddress) {
|
|
262
|
+
wormholeAddress = await this.hubContract.wormhole();
|
|
263
|
+
this.cachedWormholeAddress = wormholeAddress;
|
|
264
|
+
}
|
|
265
|
+
const wormhole = new ethers.Contract(
|
|
266
|
+
wormholeAddress,
|
|
267
|
+
["function messageFee() view returns (uint256)"],
|
|
268
|
+
this.provider
|
|
269
|
+
);
|
|
270
|
+
const fee = await wormhole.messageFee();
|
|
271
|
+
const value = BigInt(fee.toString());
|
|
272
|
+
this.cachedMessageFee = { value, expiresAt: now + 3e4 };
|
|
273
|
+
return value;
|
|
254
274
|
}
|
|
255
275
|
async buildTransferPayload(params) {
|
|
256
276
|
return encodeTransferAction(
|
|
@@ -349,13 +369,41 @@ var EVMClient = class {
|
|
|
349
369
|
actionPayload,
|
|
350
370
|
nonce: Number(nonce)
|
|
351
371
|
};
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
372
|
+
const MAX_ATTEMPTS = 3;
|
|
373
|
+
const baseDelayMs = 1e3;
|
|
374
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
375
|
+
let response;
|
|
376
|
+
let lastError;
|
|
377
|
+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
|
|
378
|
+
try {
|
|
379
|
+
response = await fetch(`${relayerUrl}/api/v1/submit`, {
|
|
380
|
+
method: "POST",
|
|
381
|
+
headers: {
|
|
382
|
+
"Content-Type": "application/json"
|
|
383
|
+
},
|
|
384
|
+
body: JSON.stringify(request)
|
|
385
|
+
});
|
|
386
|
+
const retryable = response.status >= 500 || response.status === 408 || response.status === 429;
|
|
387
|
+
if (!retryable) {
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
if (attempt === MAX_ATTEMPTS) break;
|
|
391
|
+
const retryAfter = response.headers.get("retry-after");
|
|
392
|
+
const explicitDelay = retryAfter ? parseInt(retryAfter, 10) * 1e3 : 0;
|
|
393
|
+
const backoff = explicitDelay > 0 ? explicitDelay : baseDelayMs * 2 ** (attempt - 1) + Math.floor(Math.random() * 200);
|
|
394
|
+
await sleep(backoff);
|
|
395
|
+
} catch (err) {
|
|
396
|
+
lastError = err;
|
|
397
|
+
if (attempt === MAX_ATTEMPTS) break;
|
|
398
|
+
const backoff = baseDelayMs * 2 ** (attempt - 1) + Math.floor(Math.random() * 200);
|
|
399
|
+
await sleep(backoff);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
if (!response) {
|
|
403
|
+
throw new Error(
|
|
404
|
+
`Relayer submission failed after ${MAX_ATTEMPTS} attempts: ${lastError instanceof Error ? lastError.message : String(lastError)}`
|
|
405
|
+
);
|
|
406
|
+
}
|
|
359
407
|
if (!response.ok) {
|
|
360
408
|
const error = await response.json().catch(() => ({ error: response.statusText }));
|
|
361
409
|
throw new Error(`Relayer submission failed: ${error.error || response.statusText}`);
|
|
@@ -1104,14 +1152,28 @@ var EVMClient = class {
|
|
|
1104
1152
|
return { receipt };
|
|
1105
1153
|
}
|
|
1106
1154
|
async getTransactionPolicy(identityKeyHash) {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1155
|
+
try {
|
|
1156
|
+
const result = await this.hubContract.getTransactionPolicy(identityKeyHash);
|
|
1157
|
+
return {
|
|
1158
|
+
enabled: result.enabled,
|
|
1159
|
+
threshold: Number(result.threshold),
|
|
1160
|
+
protectedActionMask: Number(result.protectedActionMask),
|
|
1161
|
+
proposalTtl: Number(result.proposalTtl),
|
|
1162
|
+
disableSessions: result.disableSessions
|
|
1163
|
+
};
|
|
1164
|
+
} catch (error) {
|
|
1165
|
+
const code = error?.code;
|
|
1166
|
+
if (code === "CALL_EXCEPTION" || code === "BAD_DATA") {
|
|
1167
|
+
return {
|
|
1168
|
+
enabled: false,
|
|
1169
|
+
threshold: 0,
|
|
1170
|
+
protectedActionMask: 0,
|
|
1171
|
+
proposalTtl: 0,
|
|
1172
|
+
disableSessions: false
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
throw error;
|
|
1176
|
+
}
|
|
1115
1177
|
}
|
|
1116
1178
|
async createTransactionProposal(signature, publicKeyX, publicKeyY, targetChain, actionPayload, signer) {
|
|
1117
1179
|
const s = signer;
|
|
@@ -1186,7 +1248,7 @@ var EVMClient = class {
|
|
|
1186
1248
|
async executeTransactionProposal(proposalId, signer) {
|
|
1187
1249
|
const s = signer;
|
|
1188
1250
|
const hub = this.hubContract.connect(s);
|
|
1189
|
-
const fee = await this.
|
|
1251
|
+
const fee = await this.getMessageFee();
|
|
1190
1252
|
const tx = await hub.executeTransactionProposal(proposalId, { value: fee });
|
|
1191
1253
|
const receipt = await tx.wait();
|
|
1192
1254
|
const sequence = this._extractSequenceFromReceipt(receipt);
|
|
@@ -1246,4 +1308,4 @@ var EVMClient = class {
|
|
|
1246
1308
|
export {
|
|
1247
1309
|
EVMClient
|
|
1248
1310
|
};
|
|
1249
|
-
//# sourceMappingURL=chunk-
|
|
1311
|
+
//# sourceMappingURL=chunk-E5HHE7IW.mjs.map
|