@naculus/connect-appkit-core 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +786 -27
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +249 -5
- package/dist/index.d.ts +249 -5
- package/dist/index.js +759 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/capabilities.ts","../src/solana-roles.ts","../src/chain-selection.ts","../src/viem-chain.ts","../src/aa-chain.ts","../src/token-chain.ts","../src/token-decimals.ts","../src/provider-errors.ts","../src/revert-reason.ts","../src/name-resolver.ts","../src/notification.ts","../src/destination.ts","../src/routing.ts","../src/web3-store.ts"],"sourcesContent":["/**\n * `@naculus/connect-appkit-core` — the half of appkit that is not about React.\n *\n * appkit's shape is \"write the Stencil components once, generate the React and\n * Vue wrappers\", and that works for anything visual. It never covered the\n * logic: the React package carried ~8.5k hand-written lines against Vue's\n * ~280, and only two files in it contain JSX. The rest was logic wearing React\n * clothes, reachable from exactly one framework.\n *\n * Everything exported here imports no framework. A React hook and a Vue\n * composable over it are each about ten lines, and they share every decision\n * that took thought rather than each making it again.\n */\n\nexport * from \"./types\";\n\n// ── EIP-5792 capabilities ─────────────────────────────────────────\nexport {\n atomicSupportFor,\n normalizeCapabilities,\n selectChainCapabilities,\n type AtomicSupport,\n type ChainCapabilities,\n} from \"./capabilities\";\n\n// ── Solana signer roles ───────────────────────────────────────────\nexport {\n readSolanaRoles,\n type SolanaIdentity,\n type SolanaPayer,\n type SolanaRoles,\n type SolanaRolesAbsence,\n type SolanaRolesSource,\n type SolanaRolesState,\n type SolanaSigner,\n type SolanaWalletFeatures,\n} from \"./solana-roles\";\n\n// ── Chains ────────────────────────────────────────────────────────\nexport {\n chainNamespace,\n chainNumber,\n chainsForNamespace,\n describeChain,\n resolveChain,\n} from \"./chain-selection\";\n\nexport { toViemChain } from \"./viem-chain\";\nexport type { ViemChainShape } from \"./viem-chain\";\n\n// ── Account abstraction ───────────────────────────────────────────\nexport * from \"./aa-chain\";\n\n// ── Tokens ────────────────────────────────────────────────────────\nexport * from \"./token-chain\";\nexport * from \"./token-decimals\";\n\n// ── Errors ────────────────────────────────────────────────────────\nexport * from \"./provider-errors\";\nexport * from \"./revert-reason\";\n\n// ── Names ─────────────────────────────────────────────────────────\nexport * from \"./name-resolver\";\n\n// ── Notifications ──────────────────────────────────────────────────\nexport * from \"./notification\";\n\n// ── Addresses ─────────────────────────────────────────────────────\nexport * from \"./destination\";\n\n// ── Routing (chain abstraction) ───────────────────────────────────\nexport * from \"./routing\";\n\n// ── Connection state machine ──────────────────────────────────────\nexport * from \"./web3-store\";\n","/**\n * EIP-5792 capability answers, normalised once.\n *\n * Deciding how to execute before sending is the whole point of\n * `wallet_getCapabilities`, and the reasoning that turns a raw answer into\n * that decision is not React's. It lived inside the React hook, which meant a\n * Vue composable could only get it by copying — and a second copy of \"absence\n * is not a denial\" is exactly the copy that drifts back into `false`.\n */\n\nimport {\n caip2ToHexChain,\n readAtomicSupport,\n type WalletCapabilities,\n} from \"@naculus/connect-core\";\n\n/**\n * Whether a wallet can execute a batch atomically.\n *\n * Three values, not two. A wallet that does not implement\n * `wallet_getCapabilities` has not said no — it has said nothing, and EIP-5792\n * is explicit that absence is not a denial. Collapsing that into `false` sends\n * every such wallet down the sequential path, which is the one where an\n * approve can land and the swap it was for can fail.\n */\nexport type AtomicSupport = \"supported\" | \"unsupported\" | \"unknown\";\n\nexport interface ChainCapabilities {\n /** CAIP-2 chain this describes. */\n chainId: string;\n atomic: AtomicSupport;\n /** Largest batch the wallet will accept, when it says. */\n maxBatchSize?: number;\n /** The raw entry, for capabilities this SDK does not model. */\n raw: WalletCapabilities;\n}\n\n/**\n * Turn a wallet's raw answer into per-chain entries.\n *\n * Entries that are not objects are dropped rather than coerced: a wallet\n * answering `null` for a chain has said nothing about it, and inventing an\n * `\"unsupported\"` there would be the same mistake as reading absence as denial.\n */\nexport function normalizeCapabilities(\n raw: Record<string, unknown> | null | undefined,\n): Record<string, ChainCapabilities> {\n const out: Record<string, ChainCapabilities> = {};\n for (const [key, entry] of Object.entries(raw ?? {})) {\n if (!entry || typeof entry !== \"object\") continue;\n const { supported, maxBatchSize } = readAtomicSupport(\n entry as Record<string, unknown>,\n );\n out[key] = {\n chainId: key,\n atomic: supported ? \"supported\" : \"unsupported\",\n ...(maxBatchSize === undefined ? {} : { maxBatchSize }),\n raw: entry as WalletCapabilities,\n };\n }\n return out;\n}\n\n/**\n * Find the entry for a chain, by CAIP-2 or by the hex form.\n *\n * Connectors normalise keys to CAIP-2, but a wallet answering in raw hex\n * through a custom connector should still be found rather than reported as\n * \"unknown\" next to an entry that is sitting right there.\n */\nexport function selectChainCapabilities(\n capabilities: Record<string, ChainCapabilities> | null | undefined,\n chainId: string | null | undefined,\n): ChainCapabilities | null {\n if (!capabilities || !chainId) return null;\n const hex = caip2ToHexChain(chainId);\n return capabilities[chainId] ?? (hex ? capabilities[hex] : undefined) ?? null;\n}\n\n/**\n * Atomic support for a chain.\n *\n * `\"unknown\"` covers every case where we have not been told: no query yet, a\n * wallet without the method, a failed query, one still in flight. A caller\n * choosing between an atomic and a sequential path needs that distinction, not\n * a confident `false`.\n */\nexport function atomicSupportFor(\n capabilities: Record<string, ChainCapabilities> | null | undefined,\n chainId: string | null | undefined,\n): AtomicSupport {\n return selectChainCapabilities(capabilities, chainId)?.atomic ?? \"unknown\";\n}\n","/**\n * Solana signer roles, read once for both frameworks.\n *\n * `@naculus/connector-solana` splits a connected wallet into `identity`,\n * `signer` and `payer`, each `null` when the wallet declared it cannot fill\n * that job. That answer is the connector's. What this module owns is the part\n * a UI has to decide before it can show anything: *why* there is no answer —\n * because nothing is connected, because the connected wallet is not Solana,\n * or because the connector predates the roles API and has not said. Those are\n * three different screens, and a hook that hands back one `null` for all of\n * them makes every consumer rediscover the distinction.\n */\n\n/** Which account this is, with no ability to sign for it. */\nexport interface SolanaIdentity {\n /** Base58 public key. */\n readonly address: string;\n /** CAIP-2 chain this account is being used on. */\n readonly chain: string;\n}\n\n/** An account that will contribute a signature without submitting anything. */\nexport interface SolanaSigner extends SolanaIdentity {\n signMessage?: (message: Uint8Array) => Promise<Uint8Array>;\n signTransaction: (transaction: Uint8Array) => Promise<Uint8Array>;\n /** Absent, not throwing, when the wallet has no batch feature. */\n signAllTransactions?: (transactions: Uint8Array[]) => Promise<Uint8Array[]>;\n}\n\n/** An account that signs and broadcasts through the wallet's own RPC. */\nexport interface SolanaPayer extends SolanaIdentity {\n /** Returns the base58 transaction signature the cluster accepted. */\n signAndSendTransaction: (transaction: Uint8Array) => Promise<string>;\n}\n\n/** What the wallet declared, recorded at discovery. Two-state on purpose. */\nexport interface SolanaWalletFeatures {\n signMessage: boolean;\n signTransaction: boolean;\n signAllTransactions: boolean;\n signAndSendTransaction: boolean;\n}\n\n/**\n * The roles a connected account can fill.\n *\n * Structurally identical to `SolanaRoles` in `@naculus/connector-solana`,\n * declared here rather than imported because this package depends only on\n * `@naculus/connect-core`, and the connector's own declaration is what its\n * `getRoles` returns — a value of that type satisfies this one unchanged.\n */\nexport interface SolanaRoles {\n identity: SolanaIdentity;\n signer: SolanaSigner | null;\n payer: SolanaPayer | null;\n features: SolanaWalletFeatures;\n}\n\n/** The part of a connector this needs. `getRoles` is optional on purpose. */\nexport interface SolanaRolesSource {\n getRoles?: (session: unknown) => SolanaRoles | null;\n}\n\n/** The part of a session this needs. */\nexport interface SessionLike {\n walletType?: string;\n}\n\n/**\n * Why `roles` is null.\n *\n * - `no_session` — nothing connected, or the connector has no live session\n * for the one the app holds (a restored session before reconnect).\n * - `not_solana` — the connected wallet is on another namespace. Not an\n * error; a Solana panel simply does not apply.\n * - `unreported` — the connector does not expose `getRoles`. An older\n * `@naculus/connector-solana`, or a custom one. The wallet has not said\n * what it can do, which is not the same as saying it can do nothing.\n */\nexport type SolanaRolesAbsence = \"no_session\" | \"not_solana\" | \"unreported\";\n\nexport type SolanaRolesState =\n | { roles: SolanaRoles; absence: null }\n | { roles: null; absence: SolanaRolesAbsence };\n\n/**\n * Read the roles for the session the app holds.\n *\n * Synchronous and pure: the connector already recorded what the wallet\n * declared, so there is nothing to await and no prompt to trigger. Reading\n * roles must never cost the user an approval dialog.\n */\nexport function readSolanaRoles(\n connector: SolanaRolesSource | null | undefined,\n session: SessionLike | null | undefined,\n): SolanaRolesState {\n if (!session) return { roles: null, absence: \"no_session\" };\n if (session.walletType !== \"solana\") {\n return { roles: null, absence: \"not_solana\" };\n }\n if (typeof connector?.getRoles !== \"function\") {\n return { roles: null, absence: \"unreported\" };\n }\n const roles = connector.getRoles(session);\n return roles\n ? { roles, absence: null }\n : { roles: null, absence: \"no_session\" };\n}\n","/**\n * Which chains a session can actually switch to, and what the current one is.\n *\n * Framework-neutral, and deliberately built on `parseChainId` from\n * `@naculus/connect-core` rather than on another `startsWith(\"eip155:\")`.\n */\n\nimport { eip155Reference, namespaceOf } from \"@naculus/connect-core\";\nimport type { ChainInfo, WalletChain } from \"./types\";\n\n/**\n * The EIP-155 chain number, or null when this is not an EVM chain.\n *\n * Callers that need a number — a viem client, an ERC-20 read — must handle\n * the null rather than defaulting, because there is no number that means\n * \"Solana\" and any stand-in would address a real EVM chain.\n */\nexport function chainNumber(chain: WalletChain): number | null {\n return eip155Reference(chain.caip2);\n}\n\n/** The namespace a chain belongs to, read from its CAIP-2 id. */\nexport function chainNamespace(chain: WalletChain): string | null {\n return namespaceOf(chain.caip2);\n}\n\n/**\n * The configured chain for a CAIP-2 id, or null.\n *\n * A string comparison now that `WalletChain` is keyed by CAIP-2. It used to\n * pull an integer out of the id and compare that, which no non-EVM chain\n * could ever match.\n */\nexport function resolveChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain | null {\n if (!chainId) return null;\n return chains.find((c) => c.caip2 === chainId) ?? null;\n}\n\n/**\n * The chains worth offering for the session's namespace.\n *\n * This used to return every configured chain regardless of what was\n * connected, so a Solana wallet was offered Ethereum and Polygon in the\n * switcher. Clicking one asked a wallet that has no concept of EIP-155 to\n * switch to chain 137 — an action the interface presented as available and\n * that could never work.\n *\n * With no connected chain, everything is offered: nothing has been ruled out\n * yet, and hiding the list would leave a user unable to pick.\n */\nexport function chainsForNamespace(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain[] {\n if (!chainId) return chains;\n const namespace = namespaceOf(chainId);\n if (!namespace) return chains;\n return chains.filter((c) => chainNamespace(c) === namespace);\n}\n\n/**\n * A description of the connected chain for display.\n *\n * Returns something for every namespace. It used to return null for anything\n * that was not EIP-155, so a connected Solana wallet had no chain to show at\n * all and the interface fell back to \"Unknown Chain\".\n */\nexport function describeChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): ChainInfo | null {\n if (!chainId) return null;\n const namespace = namespaceOf(chainId);\n if (!namespace) return null;\n\n const known = resolveChain(chains, chainId);\n if (known) {\n return { namespace, chainId, name: known.name, selected: true };\n }\n\n // No configured entry. Name it by its CAIP-2 reference rather than\n // inventing one: \"Chain 5\" for a Solana cluster would be a fabrication, and\n // the reference is at least something a user can look up.\n const reference = chainId.slice(namespace.length + 1);\n return {\n namespace,\n chainId,\n name: namespace === \"eip155\" ? `Chain ${reference}` : reference,\n selected: true,\n };\n}\n","/**\n * The viem `Chain` shape for a configured EVM chain.\n *\n * Three hooks each built this inline — `useBalance`, `useTokenBalance` and\n * `useViemClient` — with identical bodies and the same `?? \"ETH\"` in each.\n * Three copies of a fallback is three places for it to be wrong.\n *\n * Returns a plain object rather than importing viem, so this package stays\n * free of a dependency only the React bindings need. The shape satisfies\n * viem's `Chain` structurally.\n */\n\nimport { CHAINS } from \"@naculus/connect-core\";\nimport type { WalletChain } from \"./types\";\n\nexport interface ViemChainShape {\n id: number;\n name: string;\n nativeCurrency: { name: string; symbol: string; decimals: number };\n rpcUrls: {\n default: { http: string[] };\n public: { http: string[] };\n };\n}\n\n/**\n * Build the chain descriptor a viem client needs, or null when this chain is\n * not one viem can talk to.\n *\n * Null for a non-EVM chain rather than a stand-in number: viem speaks to EVM\n * nodes, and any number chosen to fill the gap addresses a real chain that is\n * not the one connected.\n *\n * The native symbol comes from the chain's own `token`, then from the shared\n * chain registry. For an unlisted chain it stays empty rather than claiming\n * the asset is ETH. viem requires a string here; the user-facing symbol comes\n * from `useBalance().symbol`, which stays null when it is unknown.\n */\nexport function toViemChain(\n chain: WalletChain,\n chainNumber: number | null,\n): ViemChainShape | null {\n if (chainNumber === null || !chain.rpcUrl) return null;\n\n const symbol =\n chain.token ?? CHAINS[chainNumber]?.nativeCurrency?.symbol ?? \"\";\n\n return {\n id: chainNumber,\n name: chain.name,\n // Every EIP-155 native currency is 18 decimals by protocol, so this is a\n // constant rather than an assumption. ERC-20 decimals are per-token and\n // are never guessed anywhere in this codebase.\n nativeCurrency: { name: symbol, symbol, decimals: 18 },\n rpcUrls: {\n default: { http: [chain.rpcUrl] },\n public: { http: [chain.rpcUrl] },\n },\n };\n}\n","/**\n * Which EVM chain does an account-abstraction operation belong to?\n *\n * The smart-account hooks each resolved this as\n * `options.chainId ?? connectedChainId ?? \"eip155:1\"`, and each then guarded\n * with `if (connectedChainId && connectedChainId !== target)`. The guard is\n * skipped precisely when the mainnet default is used, so the one branch that\n * assumes a chain is the one branch that never checks it.\n *\n * That branch is reachable: a caller passing its own `signer` needs no\n * session, so `connectedChainId` is legitimately absent. It would then build\n * and sign a UserOperation for chain 1 — with chain 1's EntryPoint — while its\n * configured RPC and bundler point somewhere else. The chain ID is part of the\n * UserOperation hash, so the user approves a commitment to a chain they were\n * never shown.\n *\n * Resolving to undefined instead lets each caller refuse in whatever way suits\n * it. Framework-agnostic on purpose: it must not import React.\n */\n\n/** CAIP-2 for an EVM chain. The reference is a decimal chain ID with no leading zero. */\nconst EVM_CHAIN_ID = /^eip155:[1-9][0-9]*$/;\n\nexport function isEvmChainId(value: string | null | undefined): boolean {\n return typeof value === \"string\" && EVM_CHAIN_ID.test(value);\n}\n\n/**\n * The chain to operate on, or undefined when it cannot be known.\n *\n * An explicitly requested chain wins over the connected one; a malformed value\n * from either source resolves to undefined rather than being replaced by a\n * guess, because the caller asked for something specific and got it wrong.\n */\nexport function resolveEvmChainId(\n requested: string | null | undefined,\n connected: string | null | undefined,\n): string | undefined {\n const candidate = requested ?? connected ?? undefined;\n return isEvmChainId(candidate) ? candidate : undefined;\n}\n","/**\n * Does this token belong to the chain the wallet is pointed at?\n *\n * `TokenConfig.chainId` existed but was only ever read as a display label and\n * a cache key. Nothing compared it to the connected chain, so a hook handed a\n * mainnet token config while the wallet sat on Polygon would read — or\n * approve — whatever contract happens to occupy that address on Polygon.\n * Usually that address holds nothing and the call reverts, which is merely\n * confusing. When it holds a different token, `allowance()` returns a\n * plausible number for the wrong asset, and `approve()` grants a spender\n * rights over something the user never looked at.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/**\n * A mismatch, or undefined when the token is on the active chain — or when\n * there is not enough information to tell.\n *\n * Silence on \"cannot tell\" is deliberate. A token config without a chainId, or\n * a session with no resolved chain, is a gap in what the caller supplied; a\n * guess in either direction would be worse than letting the call proceed and\n * fail on its own terms.\n */\nexport function tokenChainMismatch(\n token: Pick<TokenConfig, \"address\" | \"chainId\">,\n activeChainId: number | undefined,\n): WalletError | undefined {\n if (typeof token?.chainId !== \"number\" || !Number.isFinite(token.chainId)) {\n return undefined;\n }\n if (typeof activeChainId !== \"number\" || !Number.isFinite(activeChainId)) {\n return undefined;\n }\n if (token.chainId === activeChainId) return undefined;\n\n return new WalletError(\n \"chain_mismatch\",\n `Token ${token.address} is configured for chain ${token.chainId}, but the ` +\n `wallet is on chain ${activeChainId}. Switch chains before continuing — ` +\n `the same address holds a different contract on each chain.`,\n );\n}\n","/**\n * Decimals cache keyed by the token it belongs to.\n *\n * The ERC-20 hooks cached decimals in a bare `useRef` seeded from the token\n * prop. `useRef` only takes its initial value on mount, and nothing reset it,\n * so a component that lets the user switch tokens kept the first token's\n * precision: picking USDC (6) and then DAI (18) converted \"100\" with 6\n * decimals and transferred 0.0000000001 DAI. The transaction succeeded, so\n * nothing surfaced the mistake.\n *\n * Keying the cache by the token makes a stale hit impossible without needing\n * an effect to fire first.\n */\n\nexport interface TokenIdentity {\n chainId?: number;\n address: string;\n}\n\nexport interface DecimalsCache {\n key: string;\n value: number | undefined;\n}\n\nexport function tokenKey(token: TokenIdentity): string {\n return `${token.chainId ?? \"?\"}:${token.address.toLowerCase()}`;\n}\n\nexport function createDecimalsCache(\n token: TokenIdentity,\n known?: number,\n): DecimalsCache {\n return { key: tokenKey(token), value: known };\n}\n\n/**\n * Cached decimals for `token`, or undefined when the cache holds another\n * token's value. Resets the cache as a side effect so the next write lands\n * against the right key.\n */\nexport function readDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n known?: number,\n): number | undefined {\n const key = tokenKey(token);\n if (cache.key !== key) {\n cache.key = key;\n cache.value = known;\n }\n return cache.value;\n}\n\nexport function writeDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n value: number,\n): void {\n cache.key = tokenKey(token);\n cache.value = value;\n}\n","/**\n * Normalize an EIP-1193 provider error into a WalletError.\n *\n * Hooks were collapsing every non-WalletError into one code — `useSwitchChain`\n * labelled a user pressing Cancel as `chain_unsupported`, so the UI told them\n * the chain was unavailable when they had simply declined. The codes below are\n * the ones wallets actually send, and they mean different things to a caller:\n * one is retryable by asking again, the other is not retryable at all until\n * the chain is added.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/** EIP-1193: the user rejected the request. */\nconst USER_REJECTED = 4001;\n/** EIP-3326: the wallet does not recognize the chain and must add it first. */\nconst UNRECOGNIZED_CHAIN = 4902;\n\nfunction providerCode(error: unknown): number | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"number\") return code;\n // Some wallets stringify it, and some nest the original under `data`.\n if (typeof code === \"string\" && /^-?\\d+$/.test(code)) return Number(code);\n const nested = (error as { data?: { originalError?: unknown } }).data\n ?.originalError;\n return nested ? providerCode(nested) : undefined;\n}\n\n/**\n * Map a chain-switch failure onto the code that describes it.\n *\n * `fallback` is used when the wallet gave nothing to go on, so the caller\n * still decides what an unexplained failure means in its own context.\n */\nexport function toChainSwitchError(\n error: unknown,\n fallback: WalletErrorCode = \"chain_unsupported\",\n): WalletError {\n if (error instanceof WalletError) return error;\n\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error during chain switch\";\n\n switch (providerCode(error)) {\n case USER_REJECTED:\n return new WalletError(\"chain_switch_rejected\", message, error);\n case UNRECOGNIZED_CHAIN:\n return new WalletError(\n \"chain_unsupported\",\n `${message} (the wallet does not have this chain configured)`,\n error,\n );\n default:\n return new WalletError(fallback, message, error);\n }\n}\n","/**\n * Decode an EVM revert payload into something a user can act on.\n *\n * This text is what a wallet shows when a simulation says a transaction would\n * fail, so it is worth getting right and worth sharing: the logic is pure and\n * every binding needs the same answer.\n *\n * Two things are handled that the inlined version did not. The ABI length\n * word is attacker-controlled, so a payload can declare a longer string than\n * it carries; decoding that produced a run of NUL bytes rather than an honest\n * \"could not decode\". And a Panic was reported as \"Built-in failure\" with the\n * code discarded, which is the one piece of information that distinguishes an\n * overflow from a division by zero.\n */\n\n/** keccak256(\"Error(string)\")[0:4] */\nconst ERROR_STRING_SELECTOR = \"08c379a0\";\n/** keccak256(\"Panic(uint256)\")[0:4] */\nconst PANIC_SELECTOR = \"4e487b71\";\n\n/**\n * Panic codes defined by Solidity. Unlisted codes still surface their raw\n * value rather than being flattened into a generic message.\n */\nconst PANIC_REASONS: Record<number, string> = {\n 0x01: \"assertion failed\",\n 0x11: \"arithmetic overflow or underflow\",\n 0x12: \"division or modulo by zero\",\n 0x21: \"invalid enum value\",\n 0x31: \"pop() on an empty array\",\n 0x32: \"array index out of bounds\",\n};\n\nfunction hexToUtf8(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * @param data Raw revert data from the node, with or without the 0x prefix.\n * @returns The decoded reason, or undefined when the payload is not a shape\n * this understands — callers should fall back to the RPC error text rather\n * than presenting a guess.\n */\nexport function decodeRevertReason(data: unknown): string | undefined {\n if (typeof data !== \"string\" || data.length === 0) return undefined;\n const clean = data.startsWith(\"0x\") ? data.slice(2) : data;\n if (!/^[0-9a-fA-F]*$/.test(clean)) return undefined;\n\n if (clean.startsWith(ERROR_STRING_SELECTOR)) {\n // selector(8) + offset(64) + length(64) + payload\n if (clean.length < 136) return undefined;\n const declared = Number.parseInt(clean.slice(72, 136), 16);\n if (!Number.isSafeInteger(declared) || declared <= 0) return undefined;\n const available = (clean.length - 136) / 2;\n // Refuse a payload that promises more than it carries instead of padding\n // the difference with NULs and calling it a revert reason.\n if (declared > available) return undefined;\n return hexToUtf8(clean.slice(136, 136 + declared * 2));\n }\n\n if (clean.startsWith(PANIC_SELECTOR)) {\n if (clean.length < 8 + 64) return \"Panic\";\n const code = Number.parseInt(clean.slice(8, 72), 16);\n if (!Number.isSafeInteger(code)) return \"Panic\";\n const known = PANIC_REASONS[code];\n const hex = `0x${code.toString(16).padStart(2, \"0\")}`;\n return known ? `Panic ${hex}: ${known}` : `Panic ${hex}`;\n }\n\n return undefined;\n}\n\n/** Decoded reason if available, otherwise the node's own message. */\nexport function resolveRevertReason(\n data: unknown,\n fallbackMessage: string,\n): string {\n return (\n decodeRevertReason(data) ??\n (fallbackMessage.includes(\"revert\")\n ? fallbackMessage\n : \"Transaction reverted\")\n );\n}\n","/**\n * Shared NameResolver instance for the name-resolution hooks.\n *\n * useResolveName and useLookupAddress each carried an identical getResolver\n * with its own module-level singleton, so the two directions of the same\n * lookup ran against separate resolvers and separate caches. One definition,\n * one instance.\n */\nimport { NameResolver } from \"@naculus/connect-core\";\nimport type { NameResolverConfig } from \"@naculus/connect-core\";\n\nlet sharedResolver: NameResolver | null = null;\n\n/**\n * @param config When supplied, returns a dedicated resolver rather than the\n * shared one — a caller asking for specific settings must not be handed an\n * instance configured by someone else.\n */\nexport function getResolver(config?: NameResolverConfig): NameResolver {\n if (config) return new NameResolver(config);\n if (!sharedResolver) sharedResolver = new NameResolver();\n return sharedResolver;\n}\n\n/** Test seam: drop the shared instance. */\nexport function __resetResolverForTests(): void {\n sharedResolver = null;\n}\n","/** Framework-neutral in-app notification actions and settings persistence. */\n\nimport {\n createStorageAdapter,\n type InAppChannel,\n type NotificationFrequency,\n type NotificationItem,\n type NotificationSettings,\n} from \"@naculus/connect-core\";\n\nexport interface NotificationSettingsStorage {\n getItem<T>(key: string): Promise<T | null>;\n setItem<T>(key: string, value: T): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\nexport const NOTIFICATION_SETTINGS_KEY = \"naculus_notif_react_settings\";\n\nexport const DEFAULT_NOTIFICATION_SETTINGS: NotificationSettings = {\n telegram: false,\n webpush: false,\n inapp: true,\n frequency: \"final-only\" as NotificationFrequency,\n mutedChains: [],\n mutedTypes: [],\n};\n\n/** Preserve the existing localStorage adapter and fail-open UI fallback. */\nexport function createNotificationSettingsStorage(): NotificationSettingsStorage {\n const storage = createStorageAdapter(\"local\", \"naculus_notif_\");\n return {\n getItem: async <T>(key: string): Promise<T | null> => {\n try {\n return await storage.get<T>(key);\n } catch (cause) {\n console.warn(\"useNotification: failed to read from storage:\", cause);\n return null;\n }\n },\n setItem: async <T>(key: string, value: T): Promise<void> => {\n try {\n await storage.set(key, value);\n } catch (cause) {\n console.warn(\"useNotification: failed to write to storage:\", cause);\n }\n },\n removeItem: async (key: string): Promise<void> => {\n try {\n await storage.remove(key);\n } catch (cause) {\n console.warn(\"useNotification: failed to remove from storage:\", cause);\n }\n },\n };\n}\n\nexport async function loadNotificationSettings(\n storage: NotificationSettingsStorage,\n): Promise<NotificationSettings | null> {\n return storage.getItem<NotificationSettings>(NOTIFICATION_SETTINGS_KEY);\n}\n\nexport function saveNotificationSettings(\n storage: NotificationSettingsStorage,\n settings: NotificationSettings,\n): void {\n storage.setItem(NOTIFICATION_SETTINGS_KEY, settings).catch(() => {});\n}\n\nexport function updateNotificationSettings(\n current: NotificationSettings,\n update: Partial<NotificationSettings>,\n): NotificationSettings {\n return { ...current, ...update };\n}\n\nexport function channelsUpdate(\n channels: string[],\n): Partial<NotificationSettings> {\n const update: Partial<NotificationSettings> = {};\n if (channels.includes(\"telegram\")) update.telegram = true;\n if (channels.includes(\"webpush\")) update.webpush = true;\n if (channels.includes(\"inapp\")) update.inapp = true;\n return update;\n}\n\nexport function mutedChainSettings(\n settings: NotificationSettings,\n chainId: string,\n muted: boolean,\n): Partial<NotificationSettings> {\n return {\n mutedChains: muted\n ? [...new Set([...settings.mutedChains, chainId])]\n : settings.mutedChains.filter((id) => id !== chainId),\n };\n}\n\nexport function createNotification(\n item: Omit<NotificationItem, \"id\" | \"timestamp\">,\n): NotificationItem {\n return {\n ...item,\n id: `notif_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n timestamp: Date.now(),\n };\n}\n\nfunction sendItem(\n channel: InAppChannel,\n item: NotificationItem,\n): Promise<void> {\n return channel.send({\n id: item.id,\n userId: \"\",\n txHash: item.txHash,\n chainId: \"\",\n chainName: item.chainName,\n status: item.status,\n title: item.title,\n body: item.body,\n valueFormatted: item.valueFormatted,\n explorerUrl: item.explorerUrl,\n timestamp: item.timestamp,\n });\n}\n\nexport function addInAppNotification(\n channel: InAppChannel,\n item: Omit<NotificationItem, \"id\" | \"timestamp\">,\n): void {\n void sendItem(channel, createNotification(item));\n}\n\n/** InAppChannel has no remove-one method; preserve its clear/replay behavior. */\nexport async function clearOneInAppNotification(\n channel: InAppChannel,\n id: string,\n): Promise<NotificationItem[]> {\n const remaining = channel.getHistory().filter((item) => item.id !== id);\n channel.clear();\n await Promise.all(remaining.map((item) => sendItem(channel, item)));\n return channel.getHistory();\n}\n","import { isEvmAddress, isZeroAddress } from \"@naculus/connect-core\";\n\n/**\n * Destination-address checks shared by the React hook and the Vue composable.\n *\n * Syntactic only. `\"ok\"` means none of these checks found anything wrong —\n * not that the recipient is who the user thinks. This cannot see an\n * address-poisoning lookalike, a contract that will not release the funds,\n * or a known-malicious destination. Labelling that \"safe\" once put a green\n * tick beside a scammer's address; the level is deliberately not \"safe\".\n */\n\nexport type AddressValidationLevel = \"ok\" | \"warning\" | \"blocked\";\n\n/** Machine-readable reason; the framework layer maps it to a user string. */\nexport type DestinationIssue =\n | \"empty\"\n | \"invalid_format\"\n | \"zero_address\"\n | \"burn_address\";\n\nexport interface DestinationValidation {\n isValid: boolean;\n level: AddressValidationLevel;\n issue: DestinationIssue | null;\n}\n\nconst DEAD_ADDRESSES = new Set([\n \"0x0000000000000000000000000000000000000001\",\n \"0x000000000000000000000000000000000000dead\",\n]);\n\n/**\n * Burn heuristic kept from the React hook: known sinks plus any well-formed\n * address containing \"dead\". Stricter than connect-core's prefix-only\n * `isBurnAddress`; unifying the two is a connect-lib change.\n */\nexport function isBurnDestination(address: string): boolean {\n const lower = address.toLowerCase();\n return DEAD_ADDRESSES.has(lower) || lower.includes(\"dead\");\n}\n\nexport function validateDestination(address: string): DestinationValidation {\n if (!address) return { isValid: false, level: \"blocked\", issue: \"empty\" };\n if (!isEvmAddress(address)) {\n return { isValid: false, level: \"blocked\", issue: \"invalid_format\" };\n }\n if (isZeroAddress(address)) {\n return { isValid: false, level: \"blocked\", issue: \"zero_address\" };\n }\n if (isBurnDestination(address)) {\n return { isValid: false, level: \"blocked\", issue: \"burn_address\" };\n }\n // Nothing wrong was found. That is not the same as safe.\n return { isValid: true, level: \"ok\", issue: null };\n}\n\n/**\n * The bare `0x…` account from either a CAIP-10 id (`eip155:1:0x…`) or a plain\n * hex address; null when it is neither. Hooks and composables should not each\n * carry their own copy of this split.\n */\nexport function bareEvmAddress(\n account: string | null | undefined,\n): `0x${string}` | null {\n if (!account) return null;\n const value = account.includes(\":\") ? account.split(\":\").pop() : account;\n return value && isEvmAddress(value) ? (value as `0x${string}`) : null;\n}\n","import { isValidAddress } from \"@naculus/connect-core\";\n\n/**\n * Chain-abstraction (routing) domain types and the few decisions the React\n * hooks and Vue composables share. The hooks inject the actual quote /\n * compare / execute functions; nothing here talks to a network.\n */\n\n// ── Quotes ────────────────────────────────────────────────────────\n\nexport interface RouteQuote {\n routeId: string;\n provider: string;\n netReceiveFormatted: string;\n toTokenSymbol: string;\n}\n\nexport interface RouteQuoteOptions {\n sortBy?: \"cost\" | \"time\" | \"balance\";\n maxSlippage?: number;\n}\n\nexport interface RouteQuoteInput {\n fromChain: string;\n toChain: string;\n fromToken: string;\n toToken?: string;\n amount: string;\n options?: RouteQuoteOptions;\n}\n\nexport type GetRouteQuotes = (\n from: string,\n to: string,\n token: string,\n amount: string,\n options?: RouteQuoteOptions,\n toToken?: string,\n) => Promise<RouteQuote[]>;\n\n/**\n * `BigInt()` throws on anything that is not a decimal integer — \"1.5\", \"abc\",\n * \"1e18\" — so a user typing into an amount field must not reach it. Only a\n * positive base-unit integer is a quotable amount.\n */\nexport function isPositiveIntegerAmount(amount: string): boolean {\n return /^(?:0|[1-9][0-9]*)$/.test(amount) && BigInt(amount) > 0n;\n}\n\n/** True when every field a quote needs is present and the amount is quotable. */\nexport function isQuotableInput(input: RouteQuoteInput): boolean {\n return Boolean(\n input.fromChain &&\n input.toChain &&\n input.fromToken &&\n isPositiveIntegerAmount(input.amount),\n );\n}\n\n// ── Cost comparison ───────────────────────────────────────────────\n\nexport interface CostComparison {\n chain: string;\n chainName: string;\n totalCost: string;\n gasCost: string;\n estimatedTimeMs: number;\n}\n\nexport type CostComparisonOperation =\n | \"send_erc20\"\n | \"swap\"\n | \"bridge\"\n | (string & {});\n\nexport interface CostComparisonOptions {\n amount?: string;\n token?: string;\n [key: string]: unknown;\n}\n\nexport interface CompareCostsInput {\n operation: CostComparisonOperation;\n chains: string[];\n options?: CostComparisonOptions;\n}\n\nexport type CompareCosts = (\n operation: string,\n chains: string[],\n options?: CostComparisonOptions,\n) => Promise<CostComparison[]>;\n\n/**\n * Value key for a compare-costs input. `chains` is an array and `options` an\n * object; keying on identity re-fired the fetch on every render/reactive tick\n * for a caller writing the natural inline literal — an unbounded loop against\n * a cost API.\n */\nexport function compareCostsKey(input: CompareCostsInput): string {\n const options = input.options;\n const optionsKey = options\n ? Object.keys(options)\n .sort()\n .map((key) => {\n const value = options[key];\n return `${key}=${\n typeof value === \"object\" && value !== null\n ? \"[object]\"\n : String(value)\n }`;\n })\n .join(\"&\")\n : \"\";\n return `${input.operation}|${(input.chains ?? []).join(\",\")}|${optionsKey}`;\n}\n\n// ── Execution ─────────────────────────────────────────────────────\n\nexport interface ExecutableQuote {\n routeId: string;\n provider: string;\n totalCost?: bigint;\n estimatedTimeMs?: number;\n toChain?: string;\n}\n\nexport interface ExecuteRouteResult {\n fromTxHash: string;\n toTxHash?: string;\n}\n\nexport interface ExecuteRouteOptions {\n timeoutMs?: number;\n gasLimit?: bigint;\n}\n\nexport interface ExecuteRouteError {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport type ExecuteRoute = (\n quote: ExecutableQuote,\n recipient: string,\n options?: ExecuteRouteOptions,\n) => Promise<ExecuteRouteResult>;\n\n/**\n * Recipient check before a cross-chain execution. An empty recipient is wrong\n * on every chain. Beyond that the destination namespace decides: when the\n * quote names `toChain`, the address is validated for that namespace; when it\n * does not, this returns null and the executor decides, rather than rejecting\n * a valid non-EVM address on a guess.\n */\nexport function validateRouteRecipient(\n quote: ExecutableQuote | null | undefined,\n recipient: string,\n): ExecuteRouteError | null {\n if (typeof recipient !== \"string\" || recipient.trim() === \"\") {\n return {\n code: \"invalid_recipient\",\n message: \"A recipient address is required\",\n };\n }\n const namespace = quote?.toChain?.split(\":\")[0];\n if (namespace && !isValidAddress(recipient, namespace)) {\n return {\n code: \"invalid_recipient\",\n message: `\"${recipient}\" is not a valid ${namespace} address for the destination chain ${quote?.toChain}`,\n };\n }\n return null;\n}\n\n/** Normalise whatever an executor threw into the hook's error shape. */\nexport function toExecuteRouteError(cause: unknown): ExecuteRouteError {\n const error = cause as {\n code?: string;\n message?: string;\n details?: Record<string, unknown>;\n };\n return {\n code: error?.code ?? \"execution_failed\",\n message: error?.message ?? String(cause),\n details: error?.details,\n };\n}\n","/**\n * Framework-agnostic core of the connect provider.\n *\n * appkit's stated shape is \"write the Stencil components once, generate the\n * React and Vue wrappers\". In practice `react/` carries ~8.5k hand-written\n * lines against `vue/`'s ~280, and only two files in `react/src` contain JSX —\n * the rest is logic wearing React clothes. Web Components also cannot serve\n * React Native or Flutter, so the presentation layer was never going to be the\n * thing worth sharing.\n *\n * This module is the first piece moved out: the state machine and the pure\n * helpers around it, with no React import. Everything here is consumable from\n * Vue, Svelte, or a native binding as-is, and `web3-store.test.ts` asserts the\n * absence of a framework import so the boundary cannot rot back.\n */\nimport { logger } from \"@naculus/connect-core\";\nimport type { ConnectionStatus, Web3State } from \"./types\";\n\n// ── Async helpers ──────────────────────────────────────────────────────\n\nexport function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n label = \"Operation\",\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<T>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(`${label} timed out after ${ms}ms`)),\n ms,\n );\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n });\n}\n\nexport interface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n label?: string;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= options.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (attempt < options.maxRetries) {\n const delay = options.baseDelay * 2 ** attempt;\n logger.warn(\n \"appkit/core\",\n `Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n throw lastError;\n}\n\n// ── CAIP normalisation ─────────────────────────────────────────────────\n\n/** Convert EIP-1193 chainChanged values into the CAIP-2 form used by sessions. */\nexport function normalizeEip155ChainId(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n try {\n if (value.startsWith(\"eip155:\")) {\n const reference = value.slice(\"eip155:\".length);\n if (!/^\\d+$/.test(reference)) return undefined;\n return `eip155:${BigInt(reference).toString(10)}`;\n }\n if (/^0x[0-9a-f]+$/i.test(value) || /^\\d+$/.test(value)) {\n return `eip155:${BigInt(value).toString(10)}`;\n }\n } catch {\n // Ignore malformed wallet events rather than corrupting session state.\n }\n return undefined;\n}\n\nexport function toEip155Accounts(\n accounts: unknown[],\n chainId: string,\n): string[] {\n const reference = chainId.split(\":\")[1];\n if (!reference) return [];\n return accounts\n .filter(\n (account): account is string =>\n typeof account === \"string\" && account.length > 0,\n )\n .map((account) =>\n account.includes(\":\") ? (account.split(\":\").pop() as string) : account,\n )\n .map((account) => `eip155:${reference}:${account}`);\n}\n\n/**\n * Numeric EIP-155 chain id, or undefined for any other namespace.\n *\n * The previous implementation took the last CAIP segment and ran parseInt over\n * it, which stops at the first non-digit: `solana:5eykt4Us…` became 5 — an\n * EVM chain id — so asking for Solana mainnet's token list returned Goerli's,\n * and `xrpl:0` became chain 0. Anchor the whole reference instead.\n */\nexport function eip155ChainIdToNumber(chainId: string): number | undefined {\n const match = /^eip155:([1-9][0-9]*)$/.exec(chainId);\n if (!match) return undefined;\n const numeric = Number(match[1]);\n return Number.isSafeInteger(numeric) ? numeric : undefined;\n}\n\n// ── State machine ──────────────────────────────────────────────────────\n\nexport type Web3Action =\n | { type: \"SET_STATUS\"; payload: ConnectionStatus }\n | { type: \"SET_SESSION\"; payload: Web3State[\"session\"] }\n | { type: \"SET_ACCOUNTS\"; payload: string[] }\n | { type: \"SET_CHAIN\"; payload: string | null }\n | { type: \"SET_ERROR\"; payload: Error | null }\n | { type: \"RESET\" };\n\nexport const initialWeb3State: Web3State = {\n status: \"disconnected\",\n session: null,\n accounts: [],\n chainId: null,\n error: null,\n};\n\nexport function web3Reducer(state: Web3State, action: Web3Action): Web3State {\n switch (action.type) {\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_SESSION\":\n return { ...state, session: action.payload };\n case \"SET_ACCOUNTS\":\n return { ...state, accounts: action.payload };\n case \"SET_CHAIN\":\n return { ...state, chainId: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"RESET\":\n return initialWeb3State;\n default:\n return state;\n }\n}\n"],"mappings":"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","names":["import_connect_core","import_connect_core","chainNumber","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/capabilities.ts","../src/solana-roles.ts","../src/chain-selection.ts","../src/viem-chain.ts","../src/aa-chain.ts","../src/token-chain.ts","../src/token-decimals.ts","../src/erc20-calldata.ts","../src/provider-errors.ts","../src/revert-reason.ts","../src/simulation-endpoint.ts","../src/transaction-simulation.ts","../src/name-resolver.ts","../src/notification.ts","../src/destination.ts","../src/routing.ts","../src/session-key-manager.ts","../src/user-op-receipt.ts","../src/smart-account.ts","../src/delegation-policy.ts","../src/web3-store.ts","../src/siwx-policy.ts"],"sourcesContent":["/**\n * `@naculus/connect-appkit-core` — the half of appkit that is not about React.\n *\n * appkit's shape is \"write the Stencil components once, generate the React and\n * Vue wrappers\", and that works for anything visual. It never covered the\n * logic: the React package carried ~8.5k hand-written lines against Vue's\n * ~280, and only two files in it contain JSX. The rest was logic wearing React\n * clothes, reachable from exactly one framework.\n *\n * Everything exported here imports no framework. A React hook and a Vue\n * composable over it are each about ten lines, and they share every decision\n * that took thought rather than each making it again.\n */\n\nexport * from \"./types\";\n\n// ── EIP-5792 capabilities ─────────────────────────────────────────\nexport {\n atomicSupportFor,\n normalizeCapabilities,\n selectChainCapabilities,\n type AtomicSupport,\n type ChainCapabilities,\n} from \"./capabilities\";\n\n// ── Solana signer roles ───────────────────────────────────────────\nexport {\n readSolanaRoles,\n type SolanaIdentity,\n type SolanaPayer,\n type SolanaRoles,\n type SolanaRolesAbsence,\n type SolanaRolesSource,\n type SolanaRolesState,\n type SolanaSigner,\n type SolanaWalletFeatures,\n} from \"./solana-roles\";\n\n// ── Chains ────────────────────────────────────────────────────────\nexport {\n chainNamespace,\n chainNumber,\n chainsForNamespace,\n describeChain,\n resolveChain,\n} from \"./chain-selection\";\n\nexport { toViemChain } from \"./viem-chain\";\nexport type { ViemChainShape } from \"./viem-chain\";\n\n// ── Account abstraction ───────────────────────────────────────────\nexport * from \"./aa-chain\";\n\n// ── Tokens ────────────────────────────────────────────────────────\nexport * from \"./token-chain\";\nexport * from \"./token-decimals\";\nexport * from \"./erc20-calldata\";\n\n// ── Errors ────────────────────────────────────────────────────────\nexport * from \"./provider-errors\";\nexport * from \"./revert-reason\";\nexport * from \"./simulation-endpoint\";\nexport * from \"./transaction-simulation\";\n\n// ── Names ─────────────────────────────────────────────────────────\nexport * from \"./name-resolver\";\n\n// ── Notifications ──────────────────────────────────────────────────\nexport * from \"./notification\";\n\n// ── Addresses ─────────────────────────────────────────────────────\nexport * from \"./destination\";\n\n// ── Routing (chain abstraction) ───────────────────────────────────\nexport * from \"./routing\";\n\n// ── Session keys ──────────────────────────────────────────────────\nexport * from \"./session-key-manager\";\n\n// ── Account abstraction ───────────────────────────────────────────\nexport * from \"./user-op-receipt\";\nexport * from \"./smart-account\";\nexport * from \"./delegation-policy\";\n\n// ── Connection state machine ──────────────────────────────────────\nexport * from \"./web3-store\";\n\n// ── SIWX policy ──────────────────────────────────────────────────\nexport * from \"./siwx-policy\";\n","/**\n * EIP-5792 capability answers, normalised once.\n *\n * Deciding how to execute before sending is the whole point of\n * `wallet_getCapabilities`, and the reasoning that turns a raw answer into\n * that decision is not React's. It lived inside the React hook, which meant a\n * Vue composable could only get it by copying — and a second copy of \"absence\n * is not a denial\" is exactly the copy that drifts back into `false`.\n */\n\nimport {\n caip2ToHexChain,\n readAtomicSupport,\n type WalletCapabilities,\n} from \"@naculus/connect-core\";\n\n/**\n * Whether a wallet can execute a batch atomically.\n *\n * Three values, not two. A wallet that does not implement\n * `wallet_getCapabilities` has not said no — it has said nothing, and EIP-5792\n * is explicit that absence is not a denial. Collapsing that into `false` sends\n * every such wallet down the sequential path, which is the one where an\n * approve can land and the swap it was for can fail.\n */\nexport type AtomicSupport = \"supported\" | \"unsupported\" | \"unknown\";\n\nexport interface ChainCapabilities {\n /** CAIP-2 chain this describes. */\n chainId: string;\n atomic: AtomicSupport;\n /** Largest batch the wallet will accept, when it says. */\n maxBatchSize?: number;\n /** The raw entry, for capabilities this SDK does not model. */\n raw: WalletCapabilities;\n}\n\n/**\n * Turn a wallet's raw answer into per-chain entries.\n *\n * Entries that are not objects are dropped rather than coerced: a wallet\n * answering `null` for a chain has said nothing about it, and inventing an\n * `\"unsupported\"` there would be the same mistake as reading absence as denial.\n */\nexport function normalizeCapabilities(\n raw: Record<string, unknown> | null | undefined,\n): Record<string, ChainCapabilities> {\n const out: Record<string, ChainCapabilities> = {};\n for (const [key, entry] of Object.entries(raw ?? {})) {\n if (!entry || typeof entry !== \"object\") continue;\n const { supported, maxBatchSize } = readAtomicSupport(\n entry as Record<string, unknown>,\n );\n out[key] = {\n chainId: key,\n atomic: supported ? \"supported\" : \"unsupported\",\n ...(maxBatchSize === undefined ? {} : { maxBatchSize }),\n raw: entry as WalletCapabilities,\n };\n }\n return out;\n}\n\n/**\n * Find the entry for a chain, by CAIP-2 or by the hex form.\n *\n * Connectors normalise keys to CAIP-2, but a wallet answering in raw hex\n * through a custom connector should still be found rather than reported as\n * \"unknown\" next to an entry that is sitting right there.\n */\nexport function selectChainCapabilities(\n capabilities: Record<string, ChainCapabilities> | null | undefined,\n chainId: string | null | undefined,\n): ChainCapabilities | null {\n if (!capabilities || !chainId) return null;\n const hex = caip2ToHexChain(chainId);\n return capabilities[chainId] ?? (hex ? capabilities[hex] : undefined) ?? null;\n}\n\n/**\n * Atomic support for a chain.\n *\n * `\"unknown\"` covers every case where we have not been told: no query yet, a\n * wallet without the method, a failed query, one still in flight. A caller\n * choosing between an atomic and a sequential path needs that distinction, not\n * a confident `false`.\n */\nexport function atomicSupportFor(\n capabilities: Record<string, ChainCapabilities> | null | undefined,\n chainId: string | null | undefined,\n): AtomicSupport {\n return selectChainCapabilities(capabilities, chainId)?.atomic ?? \"unknown\";\n}\n","/**\n * Solana signer roles, read once for both frameworks.\n *\n * `@naculus/connector-solana` splits a connected wallet into `identity`,\n * `signer` and `payer`, each `null` when the wallet declared it cannot fill\n * that job. That answer is the connector's. What this module owns is the part\n * a UI has to decide before it can show anything: *why* there is no answer —\n * because nothing is connected, because the connected wallet is not Solana,\n * or because the connector predates the roles API and has not said. Those are\n * three different screens, and a hook that hands back one `null` for all of\n * them makes every consumer rediscover the distinction.\n */\n\n/** Which account this is, with no ability to sign for it. */\nexport interface SolanaIdentity {\n /** Base58 public key. */\n readonly address: string;\n /** CAIP-2 chain this account is being used on. */\n readonly chain: string;\n}\n\n/** An account that will contribute a signature without submitting anything. */\nexport interface SolanaSigner extends SolanaIdentity {\n signMessage?: (message: Uint8Array) => Promise<Uint8Array>;\n signTransaction: (transaction: Uint8Array) => Promise<Uint8Array>;\n /** Absent, not throwing, when the wallet has no batch feature. */\n signAllTransactions?: (transactions: Uint8Array[]) => Promise<Uint8Array[]>;\n}\n\n/** An account that signs and broadcasts through the wallet's own RPC. */\nexport interface SolanaPayer extends SolanaIdentity {\n /** Returns the base58 transaction signature the cluster accepted. */\n signAndSendTransaction: (transaction: Uint8Array) => Promise<string>;\n}\n\n/** What the wallet declared, recorded at discovery. Two-state on purpose. */\nexport interface SolanaWalletFeatures {\n signMessage: boolean;\n signTransaction: boolean;\n signAllTransactions: boolean;\n signAndSendTransaction: boolean;\n}\n\n/**\n * The roles a connected account can fill.\n *\n * Structurally identical to `SolanaRoles` in `@naculus/connector-solana`,\n * declared here rather than imported because this package depends only on\n * `@naculus/connect-core`, and the connector's own declaration is what its\n * `getRoles` returns — a value of that type satisfies this one unchanged.\n */\nexport interface SolanaRoles {\n identity: SolanaIdentity;\n signer: SolanaSigner | null;\n payer: SolanaPayer | null;\n features: SolanaWalletFeatures;\n}\n\n/** The part of a connector this needs. `getRoles` is optional on purpose. */\nexport interface SolanaRolesSource {\n getRoles?: (session: unknown) => SolanaRoles | null;\n}\n\n/** The part of a session this needs. */\nexport interface SessionLike {\n walletType?: string;\n}\n\n/**\n * Why `roles` is null.\n *\n * - `no_session` — nothing connected, or the connector has no live session\n * for the one the app holds (a restored session before reconnect).\n * - `not_solana` — the connected wallet is on another namespace. Not an\n * error; a Solana panel simply does not apply.\n * - `unreported` — the connector does not expose `getRoles`. An older\n * `@naculus/connector-solana`, or a custom one. The wallet has not said\n * what it can do, which is not the same as saying it can do nothing.\n */\nexport type SolanaRolesAbsence = \"no_session\" | \"not_solana\" | \"unreported\";\n\nexport type SolanaRolesState =\n | { roles: SolanaRoles; absence: null }\n | { roles: null; absence: SolanaRolesAbsence };\n\n/**\n * Read the roles for the session the app holds.\n *\n * Synchronous and pure: the connector already recorded what the wallet\n * declared, so there is nothing to await and no prompt to trigger. Reading\n * roles must never cost the user an approval dialog.\n */\nexport function readSolanaRoles(\n connector: SolanaRolesSource | null | undefined,\n session: SessionLike | null | undefined,\n): SolanaRolesState {\n if (!session) return { roles: null, absence: \"no_session\" };\n if (session.walletType !== \"solana\") {\n return { roles: null, absence: \"not_solana\" };\n }\n if (typeof connector?.getRoles !== \"function\") {\n return { roles: null, absence: \"unreported\" };\n }\n const roles = connector.getRoles(session);\n return roles\n ? { roles, absence: null }\n : { roles: null, absence: \"no_session\" };\n}\n","/**\n * Which chains a session can actually switch to, and what the current one is.\n *\n * Framework-neutral, and deliberately built on `parseChainId` from\n * `@naculus/connect-core` rather than on another `startsWith(\"eip155:\")`.\n */\n\nimport { eip155Reference, namespaceOf } from \"@naculus/connect-core\";\nimport type { ChainInfo, WalletChain } from \"./types\";\n\n/**\n * The EIP-155 chain number, or null when this is not an EVM chain.\n *\n * Callers that need a number — a viem client, an ERC-20 read — must handle\n * the null rather than defaulting, because there is no number that means\n * \"Solana\" and any stand-in would address a real EVM chain.\n */\nexport function chainNumber(chain: WalletChain): number | null {\n return eip155Reference(chain.caip2);\n}\n\n/** The namespace a chain belongs to, read from its CAIP-2 id. */\nexport function chainNamespace(chain: WalletChain): string | null {\n return namespaceOf(chain.caip2);\n}\n\n/**\n * The configured chain for a CAIP-2 id, or null.\n *\n * A string comparison now that `WalletChain` is keyed by CAIP-2. It used to\n * pull an integer out of the id and compare that, which no non-EVM chain\n * could ever match.\n */\nexport function resolveChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain | null {\n if (!chainId) return null;\n return chains.find((c) => c.caip2 === chainId) ?? null;\n}\n\n/**\n * The chains worth offering for the session's namespace.\n *\n * This used to return every configured chain regardless of what was\n * connected, so a Solana wallet was offered Ethereum and Polygon in the\n * switcher. Clicking one asked a wallet that has no concept of EIP-155 to\n * switch to chain 137 — an action the interface presented as available and\n * that could never work.\n *\n * With no connected chain, everything is offered: nothing has been ruled out\n * yet, and hiding the list would leave a user unable to pick.\n */\nexport function chainsForNamespace(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): WalletChain[] {\n if (!chainId) return chains;\n const namespace = namespaceOf(chainId);\n if (!namespace) return chains;\n return chains.filter((c) => chainNamespace(c) === namespace);\n}\n\n/**\n * A description of the connected chain for display.\n *\n * Returns something for every namespace. It used to return null for anything\n * that was not EIP-155, so a connected Solana wallet had no chain to show at\n * all and the interface fell back to \"Unknown Chain\".\n */\nexport function describeChain(\n chains: WalletChain[],\n chainId: string | null | undefined,\n): ChainInfo | null {\n if (!chainId) return null;\n const namespace = namespaceOf(chainId);\n if (!namespace) return null;\n\n const known = resolveChain(chains, chainId);\n if (known) {\n return { namespace, chainId, name: known.name, selected: true };\n }\n\n // No configured entry. Name it by its CAIP-2 reference rather than\n // inventing one: \"Chain 5\" for a Solana cluster would be a fabrication, and\n // the reference is at least something a user can look up.\n const reference = chainId.slice(namespace.length + 1);\n return {\n namespace,\n chainId,\n name: namespace === \"eip155\" ? `Chain ${reference}` : reference,\n selected: true,\n };\n}\n","/**\n * The viem `Chain` shape for a configured EVM chain.\n *\n * Three hooks each built this inline — `useBalance`, `useTokenBalance` and\n * `useViemClient` — with identical bodies and the same `?? \"ETH\"` in each.\n * Three copies of a fallback is three places for it to be wrong.\n *\n * Returns a plain object rather than importing viem, so this package stays\n * free of a dependency only the React bindings need. The shape satisfies\n * viem's `Chain` structurally.\n */\n\nimport { CHAINS } from \"@naculus/connect-core\";\nimport type { WalletChain } from \"./types\";\n\nexport interface ViemChainShape {\n id: number;\n name: string;\n nativeCurrency: { name: string; symbol: string; decimals: number };\n rpcUrls: {\n default: { http: string[] };\n public: { http: string[] };\n };\n}\n\n/**\n * Build the chain descriptor a viem client needs, or null when this chain is\n * not one viem can talk to.\n *\n * Null for a non-EVM chain rather than a stand-in number: viem speaks to EVM\n * nodes, and any number chosen to fill the gap addresses a real chain that is\n * not the one connected.\n *\n * The native symbol comes from the chain's own `token`, then from the shared\n * chain registry. For an unlisted chain it stays empty rather than claiming\n * the asset is ETH. viem requires a string here; the user-facing symbol comes\n * from `useBalance().symbol`, which stays null when it is unknown.\n */\nexport function toViemChain(\n chain: WalletChain,\n chainNumber: number | null,\n): ViemChainShape | null {\n if (chainNumber === null || !chain.rpcUrl) return null;\n\n const symbol =\n chain.token ?? CHAINS[chainNumber]?.nativeCurrency?.symbol ?? \"\";\n\n return {\n id: chainNumber,\n name: chain.name,\n // Every EIP-155 native currency is 18 decimals by protocol, so this is a\n // constant rather than an assumption. ERC-20 decimals are per-token and\n // are never guessed anywhere in this codebase.\n nativeCurrency: { name: symbol, symbol, decimals: 18 },\n rpcUrls: {\n default: { http: [chain.rpcUrl] },\n public: { http: [chain.rpcUrl] },\n },\n };\n}\n","/**\n * Which EVM chain does an account-abstraction operation belong to?\n *\n * The smart-account hooks each resolved this as\n * `options.chainId ?? connectedChainId ?? \"eip155:1\"`, and each then guarded\n * with `if (connectedChainId && connectedChainId !== target)`. The guard is\n * skipped precisely when the mainnet default is used, so the one branch that\n * assumes a chain is the one branch that never checks it.\n *\n * That branch is reachable: a caller passing its own `signer` needs no\n * session, so `connectedChainId` is legitimately absent. It would then build\n * and sign a UserOperation for chain 1 — with chain 1's EntryPoint — while its\n * configured RPC and bundler point somewhere else. The chain ID is part of the\n * UserOperation hash, so the user approves a commitment to a chain they were\n * never shown.\n *\n * Resolving to undefined instead lets each caller refuse in whatever way suits\n * it. Framework-agnostic on purpose: it must not import React.\n */\n\n/** CAIP-2 for an EVM chain. The reference is a decimal chain ID with no leading zero. */\nconst EVM_CHAIN_ID = /^eip155:[1-9][0-9]*$/;\n\nexport function isEvmChainId(value: string | null | undefined): boolean {\n return typeof value === \"string\" && EVM_CHAIN_ID.test(value);\n}\n\n/**\n * The chain to operate on, or undefined when it cannot be known.\n *\n * An explicitly requested chain wins over the connected one; a malformed value\n * from either source resolves to undefined rather than being replaced by a\n * guess, because the caller asked for something specific and got it wrong.\n */\nexport function resolveEvmChainId(\n requested: string | null | undefined,\n connected: string | null | undefined,\n): string | undefined {\n const candidate = requested ?? connected ?? undefined;\n return isEvmChainId(candidate) ? candidate : undefined;\n}\n","/**\n * Does this token belong to the chain the wallet is pointed at?\n *\n * `TokenConfig.chainId` existed but was only ever read as a display label and\n * a cache key. Nothing compared it to the connected chain, so a hook handed a\n * mainnet token config while the wallet sat on Polygon would read — or\n * approve — whatever contract happens to occupy that address on Polygon.\n * Usually that address holds nothing and the call reverts, which is merely\n * confusing. When it holds a different token, `allowance()` returns a\n * plausible number for the wrong asset, and `approve()` grants a spender\n * rights over something the user never looked at.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { TokenConfig } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/**\n * A mismatch, or undefined when the token is on the active chain — or when\n * there is not enough information to tell.\n *\n * Silence on \"cannot tell\" is deliberate. A token config without a chainId, or\n * a session with no resolved chain, is a gap in what the caller supplied; a\n * guess in either direction would be worse than letting the call proceed and\n * fail on its own terms.\n */\nexport function tokenChainMismatch(\n token: Pick<TokenConfig, \"address\" | \"chainId\">,\n activeChainId: number | undefined,\n): WalletError | undefined {\n if (typeof token?.chainId !== \"number\" || !Number.isFinite(token.chainId)) {\n return undefined;\n }\n if (typeof activeChainId !== \"number\" || !Number.isFinite(activeChainId)) {\n return undefined;\n }\n if (token.chainId === activeChainId) return undefined;\n\n return new WalletError(\n \"chain_mismatch\",\n `Token ${token.address} is configured for chain ${token.chainId}, but the ` +\n `wallet is on chain ${activeChainId}. Switch chains before continuing — ` +\n `the same address holds a different contract on each chain.`,\n );\n}\n","/**\n * Decimals cache keyed by the token it belongs to.\n *\n * The ERC-20 hooks cached decimals in a bare `useRef` seeded from the token\n * prop. `useRef` only takes its initial value on mount, and nothing reset it,\n * so a component that lets the user switch tokens kept the first token's\n * precision: picking USDC (6) and then DAI (18) converted \"100\" with 6\n * decimals and transferred 0.0000000001 DAI. The transaction succeeded, so\n * nothing surfaced the mistake.\n *\n * Keying the cache by the token makes a stale hit impossible without needing\n * an effect to fire first.\n */\n\nexport interface TokenIdentity {\n chainId?: number;\n address: string;\n}\n\nexport interface DecimalsCache {\n key: string;\n value: number | undefined;\n}\n\nexport function tokenKey(token: TokenIdentity): string {\n return `${token.chainId ?? \"?\"}:${token.address.toLowerCase()}`;\n}\n\nexport function createDecimalsCache(\n token: TokenIdentity,\n known?: number,\n): DecimalsCache {\n return { key: tokenKey(token), value: known };\n}\n\n/**\n * Cached decimals for `token`, or undefined when the cache holds another\n * token's value. Resets the cache as a side effect so the next write lands\n * against the right key.\n */\nexport function readDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n known?: number,\n): number | undefined {\n const key = tokenKey(token);\n if (cache.key !== key) {\n cache.key = key;\n cache.value = known;\n }\n return cache.value;\n}\n\nexport function writeDecimals(\n cache: DecimalsCache,\n token: TokenIdentity,\n value: number,\n): void {\n cache.key = tokenKey(token);\n cache.value = value;\n}\n","import { isChecksumAddress } from \"@naculus/connect-core\";\n\nconst UINT256_MAX = (1n << 256n) - 1n;\nconst EVM_ADDRESS = /^0x[0-9a-fA-F]{40}$/;\n\nfunction addressWord(address: string): string {\n if (\n typeof address !== \"string\" ||\n !EVM_ADDRESS.test(address) ||\n (address !== address.toLowerCase() && !isChecksumAddress(address))\n ) {\n throw new TypeError(\"Invalid EVM address checksum\");\n }\n return address.slice(2).toLowerCase().padStart(64, \"0\");\n}\n\nfunction uint256Word(value: bigint): string {\n if (typeof value !== \"bigint\" || value < 0n || value > UINT256_MAX) {\n throw new RangeError(\"Amount must be a uint256 bigint\");\n }\n return value.toString(16).padStart(64, \"0\");\n}\n\n/** Encode ERC-20 transfer(address,uint256), without signing or broadcasting. */\nexport function encodeErc20Transfer(to: string, amount: bigint): `0x${string}` {\n return `0xa9059cbb${addressWord(to)}${uint256Word(amount)}`;\n}\n\n/** Encode ERC-20 approve(address,uint256), without signing or broadcasting. */\nexport function encodeErc20Approve(\n spender: string,\n amount: bigint,\n): `0x${string}` {\n return `0x095ea7b3${addressWord(spender)}${uint256Word(amount)}`;\n}\n\n/** Encode ERC-20 transferFrom(address,address,uint256), without signing or broadcasting. */\nexport function encodeErc20TransferFrom(\n from: string,\n to: string,\n amount: bigint,\n): `0x${string}` {\n return `0x23b872dd${addressWord(from)}${addressWord(to)}${uint256Word(amount)}`;\n}\n","/**\n * Normalize an EIP-1193 provider error into a WalletError.\n *\n * Hooks were collapsing every non-WalletError into one code — `useSwitchChain`\n * labelled a user pressing Cancel as `chain_unsupported`, so the UI told them\n * the chain was unavailable when they had simply declined. The codes below are\n * the ones wallets actually send, and they mean different things to a caller:\n * one is retryable by asking again, the other is not retryable at all until\n * the chain is added.\n *\n * Framework-agnostic on purpose: it must not import React.\n */\n\nimport type { WalletErrorCode } from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/** EIP-1193: the user rejected the request. */\nconst USER_REJECTED = 4001;\n/** EIP-3326: the wallet does not recognize the chain and must add it first. */\nconst UNRECOGNIZED_CHAIN = 4902;\n\nfunction providerCode(error: unknown): number | undefined {\n if (!error || typeof error !== \"object\") return undefined;\n const code = (error as { code?: unknown }).code;\n if (typeof code === \"number\") return code;\n // Some wallets stringify it, and some nest the original under `data`.\n if (typeof code === \"string\" && /^-?\\d+$/.test(code)) return Number(code);\n const nested = (error as { data?: { originalError?: unknown } }).data\n ?.originalError;\n return nested ? providerCode(nested) : undefined;\n}\n\n/**\n * Map a chain-switch failure onto the code that describes it.\n *\n * `fallback` is used when the wallet gave nothing to go on, so the caller\n * still decides what an unexplained failure means in its own context.\n */\nexport function toChainSwitchError(\n error: unknown,\n fallback: WalletErrorCode = \"chain_unsupported\",\n): WalletError {\n if (error instanceof WalletError) return error;\n\n const message =\n error instanceof Error\n ? error.message\n : \"Unknown error during chain switch\";\n\n switch (providerCode(error)) {\n case USER_REJECTED:\n return new WalletError(\"chain_switch_rejected\", message, error);\n case UNRECOGNIZED_CHAIN:\n return new WalletError(\n \"chain_unsupported\",\n `${message} (the wallet does not have this chain configured)`,\n error,\n );\n default:\n return new WalletError(fallback, message, error);\n }\n}\n","/**\n * Decode an EVM revert payload into something a user can act on.\n *\n * This text is what a wallet shows when a simulation says a transaction would\n * fail, so it is worth getting right and worth sharing: the logic is pure and\n * every binding needs the same answer.\n *\n * Two things are handled that the inlined version did not. The ABI length\n * word is attacker-controlled, so a payload can declare a longer string than\n * it carries; decoding that produced a run of NUL bytes rather than an honest\n * \"could not decode\". And a Panic was reported as \"Built-in failure\" with the\n * code discarded, which is the one piece of information that distinguishes an\n * overflow from a division by zero.\n */\n\n/** keccak256(\"Error(string)\")[0:4] */\nconst ERROR_STRING_SELECTOR = \"08c379a0\";\n/** keccak256(\"Panic(uint256)\")[0:4] */\nconst PANIC_SELECTOR = \"4e487b71\";\n\n/**\n * Panic codes defined by Solidity. Unlisted codes still surface their raw\n * value rather than being flattened into a generic message.\n */\nconst PANIC_REASONS: Record<number, string> = {\n 0x01: \"assertion failed\",\n 0x11: \"arithmetic overflow or underflow\",\n 0x12: \"division or modulo by zero\",\n 0x21: \"invalid enum value\",\n 0x31: \"pop() on an empty array\",\n 0x32: \"array index out of bounds\",\n};\n\nfunction hexToUtf8(hex: string): string {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * @param data Raw revert data from the node, with or without the 0x prefix.\n * @returns The decoded reason, or undefined when the payload is not a shape\n * this understands — callers should fall back to the RPC error text rather\n * than presenting a guess.\n */\nexport function decodeRevertReason(data: unknown): string | undefined {\n if (typeof data !== \"string\" || data.length === 0) return undefined;\n const clean = data.startsWith(\"0x\") ? data.slice(2) : data;\n if (!/^[0-9a-fA-F]*$/.test(clean)) return undefined;\n\n if (clean.startsWith(ERROR_STRING_SELECTOR)) {\n // selector(8) + offset(64) + length(64) + payload\n if (clean.length < 136) return undefined;\n const declared = Number.parseInt(clean.slice(72, 136), 16);\n if (!Number.isSafeInteger(declared) || declared <= 0) return undefined;\n const available = (clean.length - 136) / 2;\n // Refuse a payload that promises more than it carries instead of padding\n // the difference with NULs and calling it a revert reason.\n if (declared > available) return undefined;\n return hexToUtf8(clean.slice(136, 136 + declared * 2));\n }\n\n if (clean.startsWith(PANIC_SELECTOR)) {\n if (clean.length < 8 + 64) return \"Panic\";\n const code = Number.parseInt(clean.slice(8, 72), 16);\n if (!Number.isSafeInteger(code)) return \"Panic\";\n const known = PANIC_REASONS[code];\n const hex = `0x${code.toString(16).padStart(2, \"0\")}`;\n return known ? `Panic ${hex}: ${known}` : `Panic ${hex}`;\n }\n\n return undefined;\n}\n\n/** Decoded reason if available, otherwise the node's own message. */\nexport function resolveRevertReason(\n data: unknown,\n fallbackMessage: string,\n): string {\n return (\n decodeRevertReason(data) ??\n (fallbackMessage.includes(\"revert\")\n ? fallbackMessage\n : \"Transaction reverted\")\n );\n}\n","import { WalletError } from \"@naculus/connect-core\";\nimport { chainNumber } from \"./chain-selection\";\nimport type { WalletChain } from \"./types\";\n\n/** Resolve a simulation target without ever guessing a default chain. */\nexport function resolveSimulationEndpoint(\n requestedChainId: number | undefined,\n fallbackChainId: number | undefined,\n requestedRpcUrl?: string,\n fallbackRpcUrl?: string,\n): { chainId: number; rpcUrl: string | undefined } {\n const chainId = requestedChainId ?? fallbackChainId;\n if (chainId === undefined) {\n throw new WalletError(\n \"invalid_chain\",\n \"No chain to simulate on. Connect a wallet or pass a chainId.\",\n );\n }\n if (\n requestedChainId !== undefined &&\n fallbackChainId !== undefined &&\n requestedChainId !== fallbackChainId &&\n requestedRpcUrl === undefined\n ) {\n throw new WalletError(\n \"invalid_chain\",\n \"Simulation chain override requires an RPC URL for that chain.\",\n );\n }\n return { chainId, rpcUrl: requestedRpcUrl ?? fallbackRpcUrl };\n}\n\n/** Resolve the chain from an explicit override or CAIP-2 chain context. */\nexport function resolveContextSimulationEndpoint(\n requestedChainId: number | undefined,\n currentChain: WalletChain | null | undefined,\n): { chainId: number; rpcUrl: string | undefined } {\n const contextChainId = currentChain\n ? (chainNumber(currentChain) ?? undefined)\n : undefined;\n if (\n requestedChainId !== undefined &&\n currentChain &&\n requestedChainId !== contextChainId\n ) {\n throw new WalletError(\n \"invalid_chain\",\n \"Simulation chain does not match the connected chain endpoint.\",\n );\n }\n return resolveSimulationEndpoint(\n requestedChainId,\n contextChainId,\n undefined,\n currentChain?.rpcUrl,\n );\n}\n","import { type SimulationResult, WalletError } from \"@naculus/connect-core\";\nimport { resolveRevertReason } from \"./revert-reason\";\nimport { resolveContextSimulationEndpoint } from \"./simulation-endpoint\";\nimport type { WalletChain } from \"./types\";\n\nexport interface SimulationTransaction {\n to: string;\n value?: string;\n data?: string;\n gas?: string;\n}\n\nexport interface SimulationCallClient {\n chain?: { id: number };\n call(args: {\n to: `0x${string}`;\n data: `0x${string}`;\n value: bigint;\n from?: `0x${string}`;\n }): Promise<unknown>;\n}\n\nexport interface TransactionSimulationContext {\n chainId?: number;\n currentChain?: WalletChain | null;\n publicClient?: SimulationCallClient | null;\n evmAccount?: string | null;\n fetcher?: typeof fetch;\n}\n\nconst coverage = {\n balanceChanges: false,\n approvalChanges: false,\n risk: false,\n} as const;\n\nfunction baseResult(\n status: SimulationResult[\"status\"],\n summary: string,\n changesDetected: boolean,\n warnings: SimulationResult[\"riskAssessment\"][\"warnings\"] = [],\n): SimulationResult {\n return {\n status,\n coverage,\n balanceChanges: [],\n approvalChanges: [],\n riskAssessment: { level: \"unknown\", score: 0, warnings },\n provider: \"eth_call\",\n summary,\n changesDetected,\n };\n}\n\n/** Basic revert check only: never claims asset changes or risk coverage. */\nexport async function simulateTransactionPreview(\n tx: SimulationTransaction | undefined,\n context: TransactionSimulationContext,\n): Promise<SimulationResult> {\n if (!tx)\n return baseResult(\"unavailable\", \"No transaction to simulate\", false);\n\n const { chainId, rpcUrl } = resolveContextSimulationEndpoint(\n context.chainId,\n context.currentChain,\n );\n const from = context.evmAccount?.includes(\":\")\n ? context.evmAccount.split(\":\").pop()\n : context.evmAccount;\n\n if (context.publicClient) {\n if (context.publicClient.chain?.id !== chainId) {\n throw new WalletError(\n \"invalid_chain\",\n \"Simulation client chain does not match the requested chain.\",\n );\n }\n try {\n await context.publicClient.call({\n to: tx.to as `0x${string}`,\n data: (tx.data ?? \"0x\") as `0x${string}`,\n value: tx.value ? BigInt(tx.value) : 0n,\n ...(from ? { from: from as `0x${string}` } : {}),\n });\n return {\n ...baseResult(\n \"success\",\n \"Transaction simulation succeeded (basic revert check only)\",\n true,\n ),\n gasInfo: tx.gas\n ? { gasLimit: BigInt(tx.gas), estimatedFeeEth: \"0\" }\n : undefined,\n };\n } catch (cause) {\n const error = cause as {\n message?: string;\n data?: unknown;\n cause?: { data?: unknown };\n };\n const reason = resolveRevertReason(\n error?.data ?? error?.cause?.data,\n error?.message ?? String(cause),\n );\n return {\n ...baseResult(\n \"reverted\",\n reason ? `Transaction reverted: ${reason}` : \"Transaction reverted\",\n false,\n [\n {\n category: \"simulation_failed\",\n severity: \"high\",\n message: reason\n ? `Transaction would revert: ${reason}`\n : \"Transaction would revert\",\n },\n ],\n ),\n revertReason: reason,\n };\n }\n }\n\n if (!rpcUrl) {\n return baseResult(\n \"unavailable\",\n \"Simulation unavailable: no RPC URL\",\n false,\n [\n {\n category: \"simulation_failed\",\n severity: \"low\",\n message: \"No RPC URL or public client available for simulation\",\n },\n ],\n );\n }\n\n try {\n const response = await (context.fetcher ?? fetch)(rpcUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: Date.now(),\n method: \"eth_call\",\n params: [\n {\n to: tx.to,\n from,\n data: tx.data ?? \"0x\",\n value: tx.value ?? \"0x0\",\n },\n \"latest\",\n ],\n }),\n });\n const json = (await response.json()) as { error?: { message?: string } };\n if (json.error) {\n return baseResult(\"reverted\", \"Transaction reverted\", false, [\n {\n category: \"simulation_failed\",\n severity: \"high\",\n message: `Transaction would revert: ${json.error.message}`,\n },\n ]);\n }\n return baseResult(\"success\", \"Transaction simulation succeeded\", true);\n } catch (cause) {\n const error = cause as { message?: string };\n return baseResult(\n \"unavailable\",\n \"Simulation unavailable due to network error\",\n false,\n [\n {\n category: \"simulation_failed\",\n severity: \"medium\",\n message: `Network error: ${error?.message ?? \"Unknown\"}`,\n },\n ],\n );\n }\n}\n","/**\n * Shared NameResolver instance for the name-resolution hooks.\n *\n * useResolveName and useLookupAddress each carried an identical getResolver\n * with its own module-level singleton, so the two directions of the same\n * lookup ran against separate resolvers and separate caches. One definition,\n * one instance.\n */\nimport { NameResolver } from \"@naculus/connect-core\";\nimport type { NameResolverConfig } from \"@naculus/connect-core\";\n\nlet sharedResolver: NameResolver | null = null;\n\n/**\n * @param config When supplied, returns a dedicated resolver rather than the\n * shared one — a caller asking for specific settings must not be handed an\n * instance configured by someone else.\n */\nexport function getResolver(config?: NameResolverConfig): NameResolver {\n if (config) return new NameResolver(config);\n if (!sharedResolver) sharedResolver = new NameResolver();\n return sharedResolver;\n}\n\n/** Test seam: drop the shared instance. */\nexport function __resetResolverForTests(): void {\n sharedResolver = null;\n}\n","/** Framework-neutral in-app notification actions and settings persistence. */\n\nimport {\n createStorageAdapter,\n type InAppChannel,\n type NotificationFrequency,\n type NotificationItem,\n type NotificationSettings,\n} from \"@naculus/connect-core\";\n\nexport interface NotificationSettingsStorage {\n getItem<T>(key: string): Promise<T | null>;\n setItem<T>(key: string, value: T): Promise<void>;\n removeItem(key: string): Promise<void>;\n}\n\nexport const NOTIFICATION_SETTINGS_KEY = \"naculus_notif_react_settings\";\n\nexport const DEFAULT_NOTIFICATION_SETTINGS: NotificationSettings = {\n telegram: false,\n webpush: false,\n inapp: true,\n frequency: \"final-only\" as NotificationFrequency,\n mutedChains: [],\n mutedTypes: [],\n};\n\n/** Preserve the existing localStorage adapter and fail-open UI fallback. */\nexport function createNotificationSettingsStorage(): NotificationSettingsStorage {\n const storage = createStorageAdapter(\"local\", \"naculus_notif_\");\n return {\n getItem: async <T>(key: string): Promise<T | null> => {\n try {\n return await storage.get<T>(key);\n } catch (cause) {\n console.warn(\n \"notification settings: failed to read from storage:\",\n cause,\n );\n return null;\n }\n },\n setItem: async <T>(key: string, value: T): Promise<void> => {\n try {\n await storage.set(key, value);\n } catch (cause) {\n console.warn(\n \"notification settings: failed to write to storage:\",\n cause,\n );\n }\n },\n removeItem: async (key: string): Promise<void> => {\n try {\n await storage.remove(key);\n } catch (cause) {\n console.warn(\n \"notification settings: failed to remove from storage:\",\n cause,\n );\n }\n },\n };\n}\n\nexport async function loadNotificationSettings(\n storage: NotificationSettingsStorage,\n): Promise<NotificationSettings | null> {\n return storage.getItem<NotificationSettings>(NOTIFICATION_SETTINGS_KEY);\n}\n\nexport function saveNotificationSettings(\n storage: NotificationSettingsStorage,\n settings: NotificationSettings,\n): void {\n storage.setItem(NOTIFICATION_SETTINGS_KEY, settings).catch(() => {});\n}\n\nexport function updateNotificationSettings(\n current: NotificationSettings,\n update: Partial<NotificationSettings>,\n): NotificationSettings {\n return { ...current, ...update };\n}\n\nexport function channelsUpdate(\n channels: string[],\n): Partial<NotificationSettings> {\n const update: Partial<NotificationSettings> = {};\n if (channels.includes(\"telegram\")) update.telegram = true;\n if (channels.includes(\"webpush\")) update.webpush = true;\n if (channels.includes(\"inapp\")) update.inapp = true;\n return update;\n}\n\nexport function mutedChainSettings(\n settings: NotificationSettings,\n chainId: string,\n muted: boolean,\n): Partial<NotificationSettings> {\n return {\n mutedChains: muted\n ? [...new Set([...settings.mutedChains, chainId])]\n : settings.mutedChains.filter((id) => id !== chainId),\n };\n}\n\nexport function createNotification(\n item: Omit<NotificationItem, \"id\" | \"timestamp\">,\n): NotificationItem {\n return {\n ...item,\n id: `notif_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,\n timestamp: Date.now(),\n };\n}\n\nfunction sendItem(\n channel: InAppChannel,\n item: NotificationItem,\n): Promise<void> {\n return channel.send({\n id: item.id,\n userId: \"\",\n txHash: item.txHash,\n chainId: \"\",\n chainName: item.chainName,\n status: item.status,\n title: item.title,\n body: item.body,\n valueFormatted: item.valueFormatted,\n explorerUrl: item.explorerUrl,\n timestamp: item.timestamp,\n });\n}\n\nexport function addInAppNotification(\n channel: InAppChannel,\n item: Omit<NotificationItem, \"id\" | \"timestamp\">,\n): void {\n void sendItem(channel, createNotification(item));\n}\n\n/** InAppChannel has no remove-one method; preserve its clear/replay behavior. */\nexport async function clearOneInAppNotification(\n channel: InAppChannel,\n id: string,\n): Promise<NotificationItem[]> {\n const remaining = channel.getHistory().filter((item) => item.id !== id);\n channel.clear();\n await Promise.all(remaining.map((item) => sendItem(channel, item)));\n return channel.getHistory();\n}\n","import {\n isBurnAddress,\n isEvmAddress,\n isZeroAddress,\n} from \"@naculus/connect-core\";\n\n/**\n * Destination-address checks shared by the React hook and the Vue composable.\n *\n * Syntactic only. `\"ok\"` means none of these checks found anything wrong —\n * not that the recipient is who the user thinks. This cannot see an\n * address-poisoning lookalike, a contract that will not release the funds,\n * or a known-malicious destination. Labelling that \"safe\" once put a green\n * tick beside a scammer's address; the level is deliberately not \"safe\".\n */\n\nexport type AddressValidationLevel = \"ok\" | \"warning\" | \"blocked\";\n\n/** Machine-readable reason; the framework layer maps it to a user string. */\nexport type DestinationIssue =\n | \"empty\"\n | \"invalid_format\"\n | \"zero_address\"\n | \"burn_address\";\n\nexport interface DestinationValidation {\n isValid: boolean;\n level: AddressValidationLevel;\n issue: DestinationIssue | null;\n}\n\n/**\n * connect-core's `isBurnAddress` is the single definition (sinks, vanity\n * prefixes, \"dead\" anywhere) since connect-lib 0.2.6; this name stays for\n * callers that imported it.\n */\nexport function isBurnDestination(address: string): boolean {\n return isBurnAddress(address);\n}\n\nexport function validateDestination(address: string): DestinationValidation {\n if (!address) return { isValid: false, level: \"blocked\", issue: \"empty\" };\n if (!isEvmAddress(address)) {\n return { isValid: false, level: \"blocked\", issue: \"invalid_format\" };\n }\n if (isZeroAddress(address)) {\n return { isValid: false, level: \"blocked\", issue: \"zero_address\" };\n }\n if (isBurnDestination(address)) {\n return { isValid: false, level: \"blocked\", issue: \"burn_address\" };\n }\n // Nothing wrong was found. That is not the same as safe.\n return { isValid: true, level: \"ok\", issue: null };\n}\n\n/**\n * The bare `0x…` account from either a CAIP-10 id (`eip155:1:0x…`) or a plain\n * hex address; null when it is neither. Hooks and composables should not each\n * carry their own copy of this split.\n */\nexport function bareEvmAddress(\n account: string | null | undefined,\n): `0x${string}` | null {\n if (!account) return null;\n const value = account.includes(\":\") ? account.split(\":\").pop() : account;\n return value && isEvmAddress(value) ? (value as `0x${string}`) : null;\n}\n","import { isValidAddress } from \"@naculus/connect-core\";\n\n/**\n * Chain-abstraction (routing) domain types and the few decisions the React\n * hooks and Vue composables share. The hooks inject the actual quote /\n * compare / execute functions; nothing here talks to a network.\n */\n\n// ── Quotes ────────────────────────────────────────────────────────\n\nexport interface RouteQuote {\n routeId: string;\n provider: string;\n netReceiveFormatted: string;\n toTokenSymbol: string;\n}\n\nexport interface RouteQuoteOptions {\n sortBy?: \"cost\" | \"time\" | \"balance\";\n maxSlippage?: number;\n}\n\nexport interface RouteQuoteInput {\n fromChain: string;\n toChain: string;\n fromToken: string;\n toToken?: string;\n amount: string;\n options?: RouteQuoteOptions;\n}\n\nexport type GetRouteQuotes = (\n from: string,\n to: string,\n token: string,\n amount: string,\n options?: RouteQuoteOptions,\n toToken?: string,\n) => Promise<RouteQuote[]>;\n\n/**\n * `BigInt()` throws on anything that is not a decimal integer — \"1.5\", \"abc\",\n * \"1e18\" — so a user typing into an amount field must not reach it. Only a\n * positive base-unit integer is a quotable amount.\n */\nexport function isPositiveIntegerAmount(amount: string): boolean {\n return /^(?:0|[1-9][0-9]*)$/.test(amount) && BigInt(amount) > 0n;\n}\n\n/** True when every field a quote needs is present and the amount is quotable. */\nexport function isQuotableInput(input: RouteQuoteInput): boolean {\n return Boolean(\n input.fromChain &&\n input.toChain &&\n input.fromToken &&\n isPositiveIntegerAmount(input.amount),\n );\n}\n\n// ── Cost comparison ───────────────────────────────────────────────\n\nexport interface CostComparison {\n chain: string;\n chainName: string;\n totalCost: string;\n gasCost: string;\n estimatedTimeMs: number;\n}\n\nexport type CostComparisonOperation =\n | \"send_erc20\"\n | \"swap\"\n | \"bridge\"\n | (string & {});\n\nexport interface CostComparisonOptions {\n amount?: string;\n token?: string;\n [key: string]: unknown;\n}\n\nexport interface CompareCostsInput {\n operation: CostComparisonOperation;\n chains: string[];\n options?: CostComparisonOptions;\n}\n\nexport type CompareCosts = (\n operation: string,\n chains: string[],\n options?: CostComparisonOptions,\n) => Promise<CostComparison[]>;\n\n/**\n * Value key for a compare-costs input. `chains` is an array and `options` an\n * object; keying on identity re-fired the fetch on every render/reactive tick\n * for a caller writing the natural inline literal — an unbounded loop against\n * a cost API.\n */\nexport function compareCostsKey(input: CompareCostsInput): string {\n const options = input.options;\n const optionsKey = options\n ? Object.keys(options)\n .sort()\n .map((key) => {\n const value = options[key];\n return `${key}=${\n typeof value === \"object\" && value !== null\n ? \"[object]\"\n : String(value)\n }`;\n })\n .join(\"&\")\n : \"\";\n return `${input.operation}|${(input.chains ?? []).join(\",\")}|${optionsKey}`;\n}\n\n// ── Execution ─────────────────────────────────────────────────────\n\nexport interface ExecutableQuote {\n routeId: string;\n provider: string;\n totalCost?: bigint;\n estimatedTimeMs?: number;\n toChain?: string;\n}\n\nexport interface ExecuteRouteResult {\n fromTxHash: string;\n toTxHash?: string;\n}\n\nexport interface ExecuteRouteOptions {\n timeoutMs?: number;\n gasLimit?: bigint;\n}\n\nexport interface ExecuteRouteError {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n}\n\nexport type ExecuteRoute = (\n quote: ExecutableQuote,\n recipient: string,\n options?: ExecuteRouteOptions,\n) => Promise<ExecuteRouteResult>;\n\n/**\n * Recipient check before a cross-chain execution. An empty recipient is wrong\n * on every chain. Beyond that the destination namespace decides: when the\n * quote names `toChain`, the address is validated for that namespace; when it\n * does not, this returns null and the executor decides, rather than rejecting\n * a valid non-EVM address on a guess.\n */\nexport function validateRouteRecipient(\n quote: ExecutableQuote | null | undefined,\n recipient: string,\n): ExecuteRouteError | null {\n if (typeof recipient !== \"string\" || recipient.trim() === \"\") {\n return {\n code: \"invalid_recipient\",\n message: \"A recipient address is required\",\n };\n }\n const namespace = quote?.toChain?.split(\":\")[0];\n if (namespace && !isValidAddress(recipient, namespace)) {\n return {\n code: \"invalid_recipient\",\n message: `\"${recipient}\" is not a valid ${namespace} address for the destination chain ${quote?.toChain}`,\n };\n }\n return null;\n}\n\n/** Normalise whatever an executor threw into the hook's error shape. */\nexport function toExecuteRouteError(cause: unknown): ExecuteRouteError {\n const error = cause as {\n code?: string;\n message?: string;\n details?: Record<string, unknown>;\n };\n return {\n code: error?.code ?? \"execution_failed\",\n message: error?.message ?? String(cause),\n details: error?.details,\n };\n}\n","import {\n DEFAULT_SESSION_KEY_CONFIG,\n LocalStorageAdapter,\n MemoryStorageAdapter,\n SessionKeyManager,\n type SessionKeyManagerConfig,\n WalletError,\n} from \"@naculus/connect-core\";\n\n/**\n * One process-wide SessionKeyManager shared by the React hooks and the Vue\n * composables. The manager owns encrypted key material and spending budgets,\n * so two instances with different limits in one page would let a caller\n * operate under limits it did not set; a second, different configuration is\n * refused rather than silently ignored.\n */\n\nlet sharedManager: SessionKeyManager | null = null;\nlet sharedFingerprint: string | null = null;\n\n/** The subset of the config that changes what a key may spend or how it is sealed. */\nexport function sessionKeyConfigFingerprint(\n config?: SessionKeyManagerConfig,\n): string {\n if (!config) return \"\";\n return JSON.stringify({\n defaultMaxTotalValue: config.defaultMaxTotalValue?.toString(),\n defaultMaxTxCount: config.defaultMaxTxCount,\n defaultExpiryMs: config.defaultExpiryMs,\n requireAllowedContracts: config.requireAllowedContracts,\n forbiddenMethods: config.forbiddenMethods,\n pbkdf2Iterations: config.pbkdf2Iterations,\n unsafeAllowWeakKdf: config.unsafeAllowWeakKdf,\n storagePrefix: config.storagePrefix,\n encryptionKey: config.encryptionKey,\n encryptionSalt: config.encryptionSalt,\n });\n}\n\nexport function getSharedSessionKeyManager(\n config?: SessionKeyManagerConfig,\n): SessionKeyManager {\n const fingerprint = sessionKeyConfigFingerprint(config);\n if (!sharedManager) {\n const storagePrefix =\n config?.storagePrefix ?? DEFAULT_SESSION_KEY_CONFIG.storagePrefix;\n sharedManager = new SessionKeyManager(\n config,\n typeof window !== \"undefined\"\n ? new LocalStorageAdapter(`${storagePrefix}:`)\n : new MemoryStorageAdapter(),\n );\n sharedFingerprint = fingerprint;\n return sharedManager;\n }\n if (fingerprint !== \"\" && fingerprint !== sharedFingerprint) {\n throw new WalletError(\n \"invalid_input\",\n \"useSessionKeys is backed by a process-wide SessionKeyManager, and a \" +\n \"different spending configuration was supplied after it was created. \" +\n \"The second configuration would be ignored, so the caller would be \" +\n \"operating under limits it did not set. Use one configuration per \" +\n \"application, or construct a SessionKeyManager directly.\",\n );\n }\n return sharedManager;\n}\n\n/** Drop the shared instance. For tests and for a full sign-out that must forget keys. */\nexport function resetSharedSessionKeyManager(): void {\n sharedManager = null;\n sharedFingerprint = null;\n}\n","import type { Address, Hex, UserOperationReceipt } from \"@naculus/connect-core\";\n\n/**\n * Validation of an ERC-4337 `eth_getUserOperationReceipt` result, shared by\n * the React hook and the Vue composable. A bundler is an untrusted party:\n * every field is checked, the hash must match the one asked for, and a\n * malformed receipt is refused instead of banked as a confirmation.\n */\n\nexport class InvalidUserOperationReceiptError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"InvalidUserOperationReceiptError\";\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\nfunction isAddress(value: unknown): value is Address {\n return typeof value === \"string\" && /^0x[0-9a-fA-F]{40}$/.test(value);\n}\nfunction isHash(value: unknown): value is Hex {\n return typeof value === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(value);\n}\nfunction isHexData(value: unknown): value is Hex {\n return typeof value === \"string\" && /^0x(?:[0-9a-fA-F]{2})*$/.test(value);\n}\nfunction parseQuantity(value: unknown, field: string): bigint {\n if (\n typeof value !== \"string\" ||\n !/^(?:0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)|(?:0|[1-9][0-9]*))$/.test(value)\n ) {\n throw new InvalidUserOperationReceiptError(\n `Bundler returned an invalid ${field}.`,\n );\n }\n return BigInt(value);\n}\n\nexport function parseUserOperationReceipt(\n value: unknown,\n expectedHash: Hex,\n): UserOperationReceipt {\n if (!isRecord(value)) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler returned an invalid UserOperation receipt.\",\n );\n }\n if (\n !isHash(value.userOpHash) ||\n value.userOpHash.toLowerCase() !== expectedHash.toLowerCase()\n ) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt does not match the requested UserOperation hash.\",\n );\n }\n if (!isAddress(value.entryPoint) || !isAddress(value.sender)) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt contains an invalid account address.\",\n );\n }\n if (\n value.paymaster !== undefined &&\n value.paymaster !== null &&\n !isAddress(value.paymaster)\n ) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt contains an invalid paymaster address.\",\n );\n }\n if (typeof value.success !== \"boolean\" || !isHash(value.transactionHash)) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt contains an invalid execution result.\",\n );\n }\n if (!Array.isArray(value.logs)) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt contains invalid logs.\",\n );\n }\n const logs = value.logs.map((candidate) => {\n if (\n !isRecord(candidate) ||\n !isAddress(candidate.address) ||\n !Array.isArray(candidate.topics) ||\n !candidate.topics.every(isHash) ||\n !isHexData(candidate.data)\n ) {\n throw new InvalidUserOperationReceiptError(\n \"Bundler receipt contains an invalid log entry.\",\n );\n }\n return {\n address: candidate.address,\n topics: candidate.topics,\n data: candidate.data,\n };\n });\n return {\n userOpHash: value.userOpHash,\n entryPoint: value.entryPoint,\n sender: value.sender,\n nonce: parseQuantity(value.nonce, \"nonce\"),\n ...(value.paymaster === undefined || value.paymaster === null\n ? {}\n : { paymaster: value.paymaster }),\n actualGasUsed: parseQuantity(value.actualGasUsed, \"actualGasUsed\"),\n actualGasCost: parseQuantity(value.actualGasCost, \"actualGasCost\"),\n success: value.success,\n transactionHash: value.transactionHash,\n logs,\n };\n}\n\n/**\n * One `eth_getUserOperationReceipt` call. Resolves to the validated receipt,\n * or null while the operation is not yet included. HTTP and JSON-RPC\n * failures throw a plain Error (retryable); a malformed receipt throws\n * InvalidUserOperationReceiptError (not retryable — the bundler is lying).\n */\nexport async function fetchUserOperationReceipt(\n bundlerUrl: string,\n hash: Hex,\n signal?: AbortSignal,\n): Promise<UserOperationReceipt | null> {\n const response = await fetch(bundlerUrl, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_getUserOperationReceipt\",\n params: [hash],\n }),\n signal,\n });\n if (!response.ok) {\n throw new Error(\n `Bundler returned HTTP ${response.status} while reading UserOperation status.`,\n );\n }\n const json = (await response.json()) as {\n result?: unknown;\n error?: { code?: unknown; message?: unknown };\n };\n if (json.error) {\n throw new Error(\n typeof json.error.message === \"string\"\n ? json.error.message\n : \"Bundler returned a JSON-RPC error.\",\n );\n }\n if (json.result === undefined || json.result === null) return null;\n return parseUserOperationReceipt(json.result, hash);\n}\n","import {\n AA_SUPPORTED_CHAINS,\n type Address,\n DEFAULT_ENTRY_POINT,\n type Hex,\n type SmartAccountConfig,\n WalletError,\n} from \"@naculus/connect-core\";\nimport { resolveEvmChainId } from \"./aa-chain\";\n\n/**\n * The decisions the smart-account hooks share, kept out of both framework\n * shells: which chain a UserOperation targets, how the account config is\n * assembled from options, and what a wallet's signature must look like.\n */\n\nexport type SmartAccountType = \"simple\" | \"light\" | \"kernel\" | \"safe\";\n\nexport interface SmartAccountOptionsLike {\n chainId?: string;\n entryPoint?: Address;\n accountType?: SmartAccountType;\n salt?: bigint;\n}\n\n/**\n * Target chain for a UserOperation. Fails closed: no chain → error rather\n * than mainnet; a connected wallet on a different chain → chain_mismatch,\n * because the signature it would produce is for the wrong domain.\n */\nexport function resolveUserOpChain(\n optionsChainId: string | undefined,\n connectedChainId: string | null | undefined,\n): string {\n const chainId = resolveEvmChainId(optionsChainId, connectedChainId);\n if (!chainId) {\n throw new WalletError(\n \"invalid_chain\",\n optionsChainId || connectedChainId\n ? `Invalid EVM chain ID: ${optionsChainId ?? connectedChainId}`\n : \"No EVM chain to send on. Connect a wallet or pass options.chainId.\",\n );\n }\n if (connectedChainId && connectedChainId !== chainId) {\n throw new WalletError(\n \"chain_mismatch\",\n `Connected chain ${connectedChainId} does not match UserOperation chain ${chainId}.`,\n );\n }\n return chainId;\n}\n\n/** Account config from owner, CAIP-2 chain and options; entry point falls back per chain. */\nexport function buildSmartAccountConfig(\n owner: Address,\n chainId: string,\n options: SmartAccountOptionsLike = {},\n): SmartAccountConfig {\n return {\n owner,\n accountType: options.accountType ?? \"simple\",\n entryPoint:\n options.entryPoint ??\n AA_SUPPORTED_CHAINS[chainId]?.entryPoint ??\n DEFAULT_ENTRY_POINT,\n chainId,\n salt: options.salt,\n };\n}\n\n/** A wallet's answer to a signing request must be non-empty even-length hex. */\nexport function assertHexSignature(value: unknown): Hex {\n if (typeof value !== \"string\" || !/^0x(?:[0-9a-fA-F]{2})+$/.test(value)) {\n throw new WalletError(\n \"signature_rejected\",\n \"Wallet returned an invalid UserOperation signature.\",\n );\n }\n return value as Hex;\n}\n","import type {\n AtomicityRequirement,\n ExecutionPlan,\n Hex,\n ScopeCheckResult,\n SessionKeyInfo,\n SessionKeyManager,\n SessionKeyScope,\n SessionKeyTransaction,\n} from \"@naculus/connect-core\";\nimport { WalletError } from \"@naculus/connect-core\";\n\n/**\n * Signed off-chain delegation policies: the complete product flow, shared by\n * React and Vue. Everything that decides whether a policy may be created,\n * is still valid, or may sign or broadcast lives here; the framework shells\n * only add state and wiring.\n *\n * Only `offchain` mode is created. An EIP-7702 or AA-module policy needs a\n * real on-chain executor; accepting those here would turn a local record into\n * a false delegation claim.\n */\n\n// ── Types ─────────────────────────────────────────────────────────\n\n/** What the execution planner says about a batch, plus the route it chose. */\nexport interface PolicyExecutionPreview extends ExecutionPlan {\n route: string | null;\n}\n\nexport interface DelegationPolicyPreview {\n policy: SessionKeyInfo | null;\n scope: ScopeCheckResult;\n execution: PolicyExecutionPreview;\n signerMatches: boolean;\n authorizationVerified: boolean;\n ready: boolean;\n broadcastReady: boolean;\n broadcastRoute: PolicyExecutionRoute | null;\n onchainAuthorizationVerified: boolean;\n broadcastSponsored: boolean | null;\n broadcastPromptless: boolean;\n reason: string;\n}\n\nexport type PolicyExecutionRoute = \"erc4337\" | \"eip7702\";\n\nexport interface PolicyExecutionCheck {\n ready: boolean;\n authorizationInstalled: boolean;\n sponsored: boolean;\n promptless: boolean;\n executorAddress?: `0x${string}`;\n reason: string;\n}\n\nexport interface PreparedPolicyExecution {\n digest: Hex;\n transaction: SessionKeyTransaction;\n payload: unknown;\n}\n\nexport interface PolicyExecutionSubmission {\n route: PolicyExecutionRoute;\n hash: Hex;\n status: \"submitted\";\n}\n\nexport interface PolicyExecutionAdapter {\n route: PolicyExecutionRoute;\n check: (request: {\n policy: SessionKeyInfo;\n transaction: SessionKeyTransaction;\n }) => Promise<PolicyExecutionCheck>;\n prepare: (request: {\n policy: SessionKeyInfo;\n transaction: SessionKeyTransaction;\n }) => Promise<PreparedPolicyExecution>;\n broadcast: (request: {\n policy: SessionKeyInfo;\n prepared: PreparedPolicyExecution;\n signature: Hex;\n }) => Promise<PolicyExecutionSubmission>;\n}\n\n/** Recovers the signer of an EIP-191 message and compares; the flow never trusts a signature unrecovered. */\nexport type PolicySignatureVerifier = (input: {\n message: string;\n signature: `0x${string}`;\n signerAddress: `0x${string}`;\n}) => Promise<boolean> | boolean;\n\nexport interface DelegationPolicyDeps {\n manager: SessionKeyManager;\n /** Origin bound into the signed message. */\n origin: string;\n /** Connected EOA, bare 0x form, or null. Read at call time. */\n signer: () => `0x${string}` | null;\n signMessage: (message: string) => Promise<string>;\n verifySignature: PolicySignatureVerifier;\n previewExecution: (\n callCount: number,\n atomicity: AtomicityRequirement,\n ) => PolicyExecutionPreview;\n /** Whether gas must be sponsored for a broadcast to count as ready. */\n sponsorship?: AtomicityRequirement;\n adapter?: PolicyExecutionAdapter;\n /** Current on-chain EIP-7702 delegation of the account. Read at call time. */\n delegation: () => {\n delegated: boolean | null;\n delegate: `0x${string}` | null;\n };\n /** A host-provided encryption key is required for persistent policies. */\n encryptionKeyConfigured: boolean;\n storageAvailable: () => boolean;\n /** Re-read the policy list after a mutation. */\n refresh: () => Promise<void>;\n}\n\n// ── Pure helpers ──────────────────────────────────────────────────\n\nfunction sorted(values: string[] | undefined): string[] | null {\n return values ? [...values].map((value) => value.toLowerCase()).sort() : null;\n}\n\n/**\n * True when the adapter's prepared transaction still means what was\n * requested. Fail-closed: a field the caller left undefined is not a\n * wildcard. An adapter may not add a target to a creation, add calldata to\n * a plain transfer, or pick a chain the caller did not name — each of those\n * changes what the session key ends up signing. Only \"no value\" and \"0\"\n * (and \"no data\" and \"0x\") are treated as the same thing.\n */\nexport function sameExecutionIntent(\n requested: SessionKeyTransaction,\n prepared: SessionKeyTransaction,\n): boolean {\n const sameHex = (left?: string, right?: string, empty?: string) => {\n const l = left === undefined ? empty : left.toLowerCase();\n const r = right === undefined ? empty : right.toLowerCase();\n return l === r;\n };\n const sameQuantity = (left?: string, right?: string) => {\n try {\n return BigInt(left ?? \"0\") === BigInt(right ?? \"0\");\n } catch {\n return false;\n }\n };\n return (\n sameHex(requested.to, prepared.to) &&\n sameHex(requested.data, prepared.data, \"0x\") &&\n sameQuantity(requested.value, prepared.value) &&\n requested.chainId === prepared.chainId\n );\n}\n\n/**\n * The exact, deterministic message the main wallet signs. Every scope field\n * is included in canonical order so a stored policy whose scope, signer or\n * origin was altered no longer verifies. There must be exactly one copy of\n * this function.\n */\nexport function buildDelegationPolicyMessage(\n policy: SessionKeyInfo,\n origin: string,\n): string {\n const tokenAllowances = policy.scope.tokenAllowances\n ? Object.entries(policy.scope.tokenAllowances)\n .map(\n ([token, value]) => [token.toLowerCase(), value.toString()] as const,\n )\n .sort(([left], [right]) => left.localeCompare(right))\n : null;\n const payload = {\n version: 1,\n origin,\n signer: policy.signerAddress.toLowerCase(),\n sessionId: policy.id,\n sessionPublicKey: policy.publicKey.toLowerCase(),\n expiresAt: new Date(policy.expiresAt).toISOString(),\n mode: policy.scope.mode,\n limits: {\n maxTotalGas: policy.scope.maxTotalGas?.toString() ?? null,\n maxGasPerTx: policy.scope.maxGasPerTx?.toString() ?? null,\n maxTotalValue: policy.scope.maxTotalValue?.toString() ?? null,\n maxValuePerTx: policy.scope.maxValuePerTx?.toString() ?? null,\n maxTxCount: policy.scope.maxTxCount ?? null,\n },\n allowedContracts: sorted(policy.scope.allowedContracts),\n allowedMethods: sorted(policy.scope.allowedMethods),\n allowedChainIds: policy.scope.allowedChainIds\n ? [...policy.scope.allowedChainIds].sort((left, right) => left - right)\n : null,\n tokenAllowances,\n };\n return `Naculus Session Policy v1\\n${JSON.stringify(payload)}`;\n}\n\n/** A stored policy is a verification candidate only in this state. */\nexport function isVerifiablePolicy(policy: SessionKeyInfo): boolean {\n return (\n policy.status === \"active\" &&\n Boolean(policy.authorized) &&\n policy.scope.mode === \"offchain\"\n );\n}\n\n// ── Flow ──────────────────────────────────────────────────────────\n\nexport interface DelegationPolicyFlow {\n verifyStoredPolicy: (policy: SessionKeyInfo) => Promise<boolean>;\n createPolicy: (scope: Partial<SessionKeyScope>) => Promise<SessionKeyInfo>;\n revokePolicy: (policyId: string) => Promise<void>;\n previewPolicyExecution: (\n policyId: string,\n tx: SessionKeyTransaction,\n callCount?: number,\n atomicity?: AtomicityRequirement,\n ) => Promise<DelegationPolicyPreview>;\n signPolicyDigest: (\n policyId: string,\n digest: `0x${string}`,\n tx: SessionKeyTransaction,\n ) => Promise<`0x${string}`>;\n executePolicy: (\n policyId: string,\n tx: SessionKeyTransaction,\n ) => Promise<PolicyExecutionSubmission>;\n}\n\nexport function createDelegationPolicyFlow(\n deps: DelegationPolicyDeps,\n): DelegationPolicyFlow {\n const { manager, origin } = deps;\n\n const verifyStoredPolicy = async (policy: SessionKeyInfo) => {\n if (!isVerifiablePolicy(policy)) return false;\n return manager.verifyOffchainAuthorization(\n policy.id,\n buildDelegationPolicyMessage(policy, origin),\n deps.verifySignature,\n );\n };\n\n const createPolicy = async (\n scope: Partial<SessionKeyScope>,\n ): Promise<SessionKeyInfo> => {\n const signer = deps.signer();\n if (!signer) {\n throw new WalletError(\"wallet_unavailable\", \"No active EVM account\");\n }\n if (scope.mode && scope.mode !== \"offchain\") {\n throw new WalletError(\n \"method_not_allowed\",\n \"This flow creates signed off-chain policies only. EIP-7702 and AA-module policies require a configured on-chain execution adapter.\",\n );\n }\n if (!deps.encryptionKeyConfigured) {\n throw new WalletError(\n \"method_not_allowed\",\n \"Persistent delegation policies require a host-provided encryptionKey. The deterministic compatibility fallback is not a production key boundary.\",\n );\n }\n if (!deps.storageAvailable()) {\n throw new WalletError(\n \"storage_unavailable\",\n \"Persistent delegation policy storage is unavailable in this browser\",\n );\n }\n let draft: SessionKeyInfo | null = null;\n try {\n draft = await manager.createSessionKey(\n { ...scope, mode: \"offchain\" },\n signer,\n );\n const message = buildDelegationPolicyMessage(draft, origin);\n const signature = await deps.signMessage(message);\n if (!/^0x[0-9a-fA-F]{130}$/.test(signature)) {\n throw new WalletError(\n \"invalid_input\",\n \"Wallet did not return a valid 65-byte EVM policy signature\",\n );\n }\n const recovers = await deps.verifySignature({\n message,\n signature: signature as `0x${string}`,\n signerAddress: signer,\n });\n if (!recovers) {\n throw new WalletError(\n \"invalid_input\",\n \"Policy signature does not recover to the connected EVM account\",\n );\n }\n await manager.setAuthorization(draft.id, {\n signerAddress: signer,\n type: \"offchain\",\n rawSignature: signature as `0x${string}`,\n message,\n });\n const authorized = (await manager.listSessions()).find(\n (policy) => policy.id === draft?.id,\n );\n if (!authorized?.authorized) {\n throw new WalletError(\n \"invalid_input\",\n \"Policy authorization was not persisted\",\n );\n }\n if (!(await verifyStoredPolicy(authorized))) {\n throw new WalletError(\n \"invalid_input\",\n \"Persisted policy signature did not verify against its stored scope and origin\",\n );\n }\n await deps.refresh();\n return authorized;\n } catch (cause) {\n // A draft that never got a valid signature must not stay usable.\n if (draft) {\n try {\n await manager.revokeSession(draft.id);\n } catch {\n // best effort; the draft is unauthorized and cannot sign anyway\n }\n }\n throw cause instanceof Error\n ? cause\n : new Error(\"Policy creation failed\");\n }\n };\n\n const revokePolicy = async (policyId: string) => {\n await manager.revokeSession(policyId);\n await deps.refresh();\n };\n\n const previewPolicyExecution = async (\n policyId: string,\n tx: SessionKeyTransaction,\n callCount = 1,\n atomicity: AtomicityRequirement = \"preferred\",\n ): Promise<DelegationPolicyPreview> => {\n const policy =\n (await manager.listSessions()).find((item) => item.id === policyId) ??\n null;\n const scope = await manager.checkSessionScope(policyId, tx);\n const plan = deps.previewExecution(callCount, atomicity);\n const signer = deps.signer();\n const authorizationVerified = policy\n ? await verifyStoredPolicy(policy)\n : false;\n const signerMatches = Boolean(\n policy &&\n signer &&\n policy.signerAddress.toLowerCase() === signer.toLowerCase(),\n );\n const adapter = deps.adapter;\n let adapterCheck: PolicyExecutionCheck | null = null;\n if (\n policy &&\n adapter &&\n authorizationVerified &&\n signerMatches &&\n scope.valid\n ) {\n try {\n adapterCheck = await adapter.check({ policy, transaction: tx });\n } catch (cause) {\n adapterCheck = {\n ready: false,\n authorizationInstalled: false,\n sponsored: false,\n promptless: false,\n reason:\n cause instanceof Error\n ? `Execution adapter check failed: ${cause.message}`\n : \"Execution adapter check failed.\",\n };\n }\n }\n const delegation = deps.delegation();\n const delegationMatches = Boolean(\n adapter?.route !== \"eip7702\" ||\n (delegation.delegated === true &&\n adapterCheck?.executorAddress &&\n delegation.delegate?.toLowerCase() ===\n adapterCheck.executorAddress.toLowerCase()),\n );\n const policyReady = Boolean(\n policy?.status === \"active\" &&\n policy.authorized &&\n authorizationVerified &&\n policy.scope.mode === \"offchain\" &&\n signerMatches &&\n scope.valid,\n );\n const adapterSponsorshipReady = Boolean(\n deps.sponsorship !== \"required\" || adapterCheck?.sponsored,\n );\n const broadcastReady = Boolean(\n policyReady &&\n callCount === 1 &&\n adapterCheck?.ready &&\n adapterCheck.authorizationInstalled &&\n adapterCheck.promptless &&\n adapterSponsorshipReady &&\n delegationMatches,\n );\n const ready = Boolean(policyReady && (plan.route || broadcastReady));\n const reason = !policy\n ? \"Policy not found.\"\n : policy.status !== \"active\"\n ? `Policy is ${policy.status}.`\n : !policy.authorized\n ? \"The main wallet has not signed this policy.\"\n : !authorizationVerified\n ? \"The persisted policy signature no longer matches its scope, signer, or origin.\"\n : !signerMatches\n ? \"The connected account is not the policy signer.\"\n : !scope.valid\n ? (scope.reason ??\n \"The transaction is outside the policy scope.\")\n : broadcastReady\n ? `The configured ${adapter?.route ?? \"AA/7702\"} adapter can submit this policy-authorized operation without another main-wallet prompt.${adapterCheck?.sponsored ? \" Gas sponsorship is guaranteed.\" : \"\"} ${adapterCheck?.reason ?? \"The on-chain execution adapter is ready.\"}`\n : !adapter\n ? `${plan.reason} The signed off-chain policy permits this request; an AA/7702 adapter is still required to broadcast without another wallet prompt.`\n : !adapterCheck?.ready ||\n !adapterCheck.authorizationInstalled\n ? `${plan.reason} ${adapterCheck?.reason ?? \"The execution adapter is not ready.\"}`\n : !adapterCheck.promptless\n ? `${plan.reason} The configured adapter would invoke the main wallet again, so promptless broadcast is not ready.`\n : !adapterSponsorshipReady\n ? `${plan.reason} Sponsored gas is required, but the configured adapter does not guarantee sponsorship.`\n : callCount !== 1\n ? `${plan.reason} This policy adapter prepares one execution at a time and cannot claim a multi-call broadcast.`\n : !delegationMatches\n ? `${plan.reason} The configured EIP-7702 executor does not match the account's on-chain delegation.`\n : !plan.route\n ? plan.reason\n : `${plan.reason} ${adapterCheck.reason}`;\n return {\n policy,\n scope,\n execution: plan,\n signerMatches,\n authorizationVerified,\n ready,\n broadcastReady,\n broadcastRoute: broadcastReady ? (adapter?.route ?? null) : null,\n onchainAuthorizationVerified: Boolean(\n adapterCheck?.authorizationInstalled && delegationMatches,\n ),\n broadcastSponsored: broadcastReady\n ? (adapterCheck?.sponsored ?? false)\n : null,\n broadcastPromptless: Boolean(broadcastReady && adapterCheck?.promptless),\n reason,\n };\n };\n\n const signVerified = (\n policyId: string,\n digest: `0x${string}`,\n tx: SessionKeyTransaction,\n ) =>\n manager.signWithVerifiedOffchainAuthorization(\n policyId,\n (authoritativePolicy) =>\n buildDelegationPolicyMessage(authoritativePolicy, origin),\n deps.verifySignature,\n digest,\n tx,\n );\n\n const signPolicyDigest = async (\n policyId: string,\n digest: `0x${string}`,\n tx: SessionKeyTransaction,\n ) => {\n const preview = await previewPolicyExecution(policyId, tx, 1, \"any\");\n if (!preview.ready) {\n throw new WalletError(\"method_not_allowed\", preview.reason);\n }\n return signVerified(policyId, digest, tx);\n };\n\n const executePolicy = async (\n policyId: string,\n tx: SessionKeyTransaction,\n ): Promise<PolicyExecutionSubmission> => {\n const adapter = deps.adapter;\n if (!adapter) {\n throw new WalletError(\n \"method_not_allowed\",\n \"No session-policy-aware AA/7702 execution adapter is configured.\",\n );\n }\n const preview = await previewPolicyExecution(policyId, tx, 1, \"any\");\n if (!preview.broadcastReady || !preview.policy) {\n throw new WalletError(\"method_not_allowed\", preview.reason);\n }\n const prepared = await adapter.prepare({\n policy: preview.policy,\n transaction: tx,\n });\n if (!/^0x[0-9a-fA-F]{64}$/.test(prepared.digest)) {\n throw new WalletError(\n \"invalid_input\",\n \"Execution adapter returned a digest that is not 32 bytes.\",\n );\n }\n if (!sameExecutionIntent(tx, prepared.transaction)) {\n throw new WalletError(\n \"invalid_input\",\n \"Execution adapter changed the requested target, value, data, or chain.\",\n );\n }\n // Re-check against what will actually be signed, not the request.\n const currentCheck = await adapter.check({\n policy: preview.policy,\n transaction: prepared.transaction,\n });\n const delegation = deps.delegation();\n const currentDelegationMatches =\n adapter.route !== \"eip7702\" ||\n (delegation.delegated === true &&\n currentCheck.executorAddress !== undefined &&\n delegation.delegate?.toLowerCase() ===\n currentCheck.executorAddress.toLowerCase());\n if (\n !currentCheck.ready ||\n !currentCheck.authorizationInstalled ||\n !currentCheck.promptless ||\n (deps.sponsorship === \"required\" && !currentCheck.sponsored) ||\n !currentDelegationMatches\n ) {\n throw new WalletError(\n \"method_not_allowed\",\n currentCheck.reason ||\n \"The on-chain policy authorization is not ready.\",\n );\n }\n const signature = await signVerified(\n policyId,\n prepared.digest,\n prepared.transaction,\n );\n const submission = await adapter.broadcast({\n policy: preview.policy,\n prepared,\n signature,\n });\n if (\n submission.route !== adapter.route ||\n submission.status !== \"submitted\" ||\n !/^0x[0-9a-fA-F]{64}$/.test(submission.hash)\n ) {\n throw new WalletError(\n \"invalid_input\",\n \"Execution adapter returned an invalid submission result.\",\n );\n }\n await deps.refresh();\n return submission;\n };\n\n return {\n verifyStoredPolicy,\n createPolicy,\n revokePolicy,\n previewPolicyExecution,\n signPolicyDigest,\n executePolicy,\n };\n}\n","/**\n * Framework-agnostic core of the connect provider.\n *\n * appkit's stated shape is \"write the Stencil components once, generate the\n * React and Vue wrappers\". In practice `react/` carries ~8.5k hand-written\n * lines against `vue/`'s ~280, and only two files in `react/src` contain JSX —\n * the rest is logic wearing React clothes. Web Components also cannot serve\n * React Native or Flutter, so the presentation layer was never going to be the\n * thing worth sharing.\n *\n * This module is the first piece moved out: the state machine and the pure\n * helpers around it, with no React import. Everything here is consumable from\n * Vue, Svelte, or a native binding as-is, and `web3-store.test.ts` asserts the\n * absence of a framework import so the boundary cannot rot back.\n */\nimport { logger } from \"@naculus/connect-core\";\nimport type { ConnectionStatus, Web3State } from \"./types\";\n\n// ── Async helpers ──────────────────────────────────────────────────────\n\nexport function withTimeout<T>(\n promise: Promise<T>,\n ms: number,\n label = \"Operation\",\n): Promise<T> {\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<T>((_, reject) => {\n timeoutId = setTimeout(\n () => reject(new Error(`${label} timed out after ${ms}ms`)),\n ms,\n );\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timeoutId !== undefined) clearTimeout(timeoutId);\n });\n}\n\nexport interface RetryOptions {\n maxRetries: number;\n baseDelay: number;\n label?: string;\n}\n\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n options: RetryOptions,\n): Promise<T> {\n let lastError: unknown;\n for (let attempt = 0; attempt <= options.maxRetries; attempt++) {\n try {\n return await fn();\n } catch (error) {\n lastError = error;\n if (attempt < options.maxRetries) {\n const delay = options.baseDelay * 2 ** attempt;\n logger.warn(\n \"appkit/core\",\n `Retry attempt ${attempt + 1}/${options.maxRetries} after ${delay}ms`,\n );\n await new Promise((resolve) => setTimeout(resolve, delay));\n }\n }\n }\n throw lastError;\n}\n\n// ── CAIP normalisation ─────────────────────────────────────────────────\n\n/** Convert EIP-1193 chainChanged values into the CAIP-2 form used by sessions. */\nexport function normalizeEip155ChainId(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n try {\n if (value.startsWith(\"eip155:\")) {\n const reference = value.slice(\"eip155:\".length);\n if (!/^\\d+$/.test(reference)) return undefined;\n return `eip155:${BigInt(reference).toString(10)}`;\n }\n if (/^0x[0-9a-f]+$/i.test(value) || /^\\d+$/.test(value)) {\n return `eip155:${BigInt(value).toString(10)}`;\n }\n } catch {\n // Ignore malformed wallet events rather than corrupting session state.\n }\n return undefined;\n}\n\nexport function toEip155Accounts(\n accounts: unknown[],\n chainId: string,\n): string[] {\n const reference = chainId.split(\":\")[1];\n if (!reference) return [];\n return accounts\n .filter(\n (account): account is string =>\n typeof account === \"string\" && account.length > 0,\n )\n .map((account) =>\n account.includes(\":\") ? (account.split(\":\").pop() as string) : account,\n )\n .map((account) => `eip155:${reference}:${account}`);\n}\n\n/**\n * Numeric EIP-155 chain id, or undefined for any other namespace.\n *\n * The previous implementation took the last CAIP segment and ran parseInt over\n * it, which stops at the first non-digit: `solana:5eykt4Us…` became 5 — an\n * EVM chain id — so asking for Solana mainnet's token list returned Goerli's,\n * and `xrpl:0` became chain 0. Anchor the whole reference instead.\n */\nexport function eip155ChainIdToNumber(chainId: string): number | undefined {\n const match = /^eip155:([1-9][0-9]*)$/.exec(chainId);\n if (!match) return undefined;\n const numeric = Number(match[1]);\n return Number.isSafeInteger(numeric) ? numeric : undefined;\n}\n\n// ── State machine ──────────────────────────────────────────────────────\n\nexport type Web3Action =\n | { type: \"SET_STATUS\"; payload: ConnectionStatus }\n | { type: \"SET_SESSION\"; payload: Web3State[\"session\"] }\n | { type: \"SET_ACCOUNTS\"; payload: string[] }\n | { type: \"SET_CHAIN\"; payload: string | null }\n | { type: \"SET_ERROR\"; payload: Error | null }\n | { type: \"RESET\" };\n\nexport const initialWeb3State: Web3State = {\n status: \"disconnected\",\n session: null,\n accounts: [],\n chainId: null,\n error: null,\n};\n\nexport function web3Reducer(state: Web3State, action: Web3Action): Web3State {\n switch (action.type) {\n case \"SET_STATUS\":\n return { ...state, status: action.payload };\n case \"SET_SESSION\":\n return { ...state, session: action.payload };\n case \"SET_ACCOUNTS\":\n return { ...state, accounts: action.payload };\n case \"SET_CHAIN\":\n return { ...state, chainId: action.payload };\n case \"SET_ERROR\":\n return { ...state, error: action.payload };\n case \"RESET\":\n return initialWeb3State;\n default:\n return state;\n }\n}\n","export interface SiwxLocation {\n host: string;\n origin: string;\n}\n\nexport interface SiwxMessageLike {\n chainId: string;\n address: string;\n domain: string;\n issuedAt?: string | null;\n expirationTime?: string | null;\n notBefore?: string | null;\n}\n\nexport interface SiwxResultLike<M extends SiwxMessageLike = SiwxMessageLike> {\n message: M;\n signature: string;\n}\n\nexport function defaultSiwxDomain(location?: SiwxLocation): string {\n return location?.host ?? \"localhost\";\n}\n\nexport function defaultSiwxUri(location?: SiwxLocation): string {\n return location?.origin ?? \"http://localhost\";\n}\n\nexport function isSiwxExpired(result: SiwxResultLike, now: Date): boolean {\n const value = result.message.expirationTime;\n if (!value) return false;\n const timestamp = new Date(value).getTime();\n return !Number.isFinite(timestamp) || timestamp <= now.getTime();\n}\n\nexport function isSiwxNotBeforeValid(\n result: SiwxResultLike,\n now: Date,\n): boolean {\n const value = result.message.notBefore;\n if (!value) return true;\n const timestamp = new Date(value).getTime();\n return Number.isFinite(timestamp) && timestamp <= now.getTime();\n}\n\nfunction randomSuffix(): string {\n const bytes = new Uint8Array(8);\n crypto.getRandomValues(bytes);\n return Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\n \"\",\n );\n}\n\nexport function siwxResultToSession<M extends SiwxMessageLike>(\n result: SiwxResultLike<M>,\n now = new Date(),\n) {\n return {\n id: `siwx_${now.getTime().toString(36)}_${randomSuffix()}`,\n chainId: result.message.chainId,\n address: result.message.address,\n domain: result.message.domain,\n message: result.message,\n signature: result.signature,\n issuedAt: result.message.issuedAt ?? now.toISOString(),\n expiresAt: result.message.expirationTime ?? null,\n refreshedAt: null,\n };\n}\n"],"mappings":"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","names":["import_connect_core","import_connect_core","chainNumber","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core","import_connect_core"]}
|