@wlfi-agent/cli 1.4.17 → 1.4.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/Cargo.lock +5 -0
  2. package/README.md +61 -28
  3. package/crates/vault-cli-admin/src/io_utils.rs +149 -1
  4. package/crates/vault-cli-admin/src/main.rs +639 -16
  5. package/crates/vault-cli-admin/src/shared_config.rs +18 -18
  6. package/crates/vault-cli-admin/src/tui/token_rpc.rs +190 -3
  7. package/crates/vault-cli-admin/src/tui/utils.rs +59 -0
  8. package/crates/vault-cli-admin/src/tui.rs +1205 -120
  9. package/crates/vault-cli-agent/Cargo.toml +1 -0
  10. package/crates/vault-cli-agent/src/io_utils.rs +163 -2
  11. package/crates/vault-cli-agent/src/main.rs +648 -32
  12. package/crates/vault-cli-daemon/Cargo.toml +4 -0
  13. package/crates/vault-cli-daemon/src/main.rs +617 -67
  14. package/crates/vault-cli-daemon/src/relay_sync.rs +776 -4
  15. package/crates/vault-cli-daemon/tests/system_keychain_helper_acl.rs +5 -0
  16. package/crates/vault-daemon/src/daemon_parts/api_impl_and_utils.rs +32 -1
  17. package/crates/vault-daemon/src/persistence.rs +637 -100
  18. package/crates/vault-daemon/src/tests.rs +1013 -3
  19. package/crates/vault-daemon/src/tests_parts/part2.rs +99 -0
  20. package/crates/vault-daemon/src/tests_parts/part4.rs +11 -7
  21. package/crates/vault-domain/src/nonce.rs +4 -0
  22. package/crates/vault-domain/src/tests.rs +616 -0
  23. package/crates/vault-policy/src/engine.rs +55 -32
  24. package/crates/vault-policy/src/tests.rs +195 -0
  25. package/crates/vault-sdk-agent/src/lib.rs +415 -22
  26. package/crates/vault-signer/Cargo.toml +3 -0
  27. package/crates/vault-signer/src/lib.rs +266 -40
  28. package/crates/vault-transport-unix/src/lib.rs +653 -5
  29. package/crates/vault-transport-xpc/src/tests.rs +531 -3
  30. package/crates/vault-transport-xpc/tests/e2e_flow.rs +3 -0
  31. package/dist/cli.cjs +663 -190
  32. package/dist/cli.cjs.map +1 -1
  33. package/package.json +5 -2
  34. package/packages/cache/.turbo/turbo-build.log +20 -20
  35. package/packages/cache/coverage/clover.xml +529 -394
  36. package/packages/cache/coverage/coverage-final.json +2 -2
  37. package/packages/cache/coverage/index.html +21 -21
  38. package/packages/cache/coverage/src/client/index.html +1 -1
  39. package/packages/cache/coverage/src/client/index.ts.html +1 -1
  40. package/packages/cache/coverage/src/errors/index.html +1 -1
  41. package/packages/cache/coverage/src/errors/index.ts.html +12 -12
  42. package/packages/cache/coverage/src/index.html +1 -1
  43. package/packages/cache/coverage/src/index.ts.html +1 -1
  44. package/packages/cache/coverage/src/service/index.html +21 -21
  45. package/packages/cache/coverage/src/service/index.ts.html +769 -313
  46. package/packages/cache/dist/{chunk-QNK6GOTI.js → chunk-KC53LH5Z.js} +35 -2
  47. package/packages/cache/dist/chunk-KC53LH5Z.js.map +1 -0
  48. package/packages/cache/dist/{chunk-QF4XKEIA.cjs → chunk-UVU7VFE3.cjs} +35 -2
  49. package/packages/cache/dist/chunk-UVU7VFE3.cjs.map +1 -0
  50. package/packages/cache/dist/index.cjs +2 -2
  51. package/packages/cache/dist/index.js +1 -1
  52. package/packages/cache/dist/service/index.cjs +2 -2
  53. package/packages/cache/dist/service/index.js +1 -1
  54. package/packages/cache/node_modules/.bin/tsc +2 -2
  55. package/packages/cache/node_modules/.bin/tsserver +2 -2
  56. package/packages/cache/node_modules/.bin/tsup +2 -2
  57. package/packages/cache/node_modules/.bin/tsup-node +2 -2
  58. package/packages/cache/node_modules/.bin/vitest +4 -4
  59. package/packages/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
  60. package/packages/cache/src/service/index.test.ts +165 -19
  61. package/packages/cache/src/service/index.ts +38 -1
  62. package/packages/config/.turbo/turbo-build.log +4 -4
  63. package/packages/config/dist/index.cjs +0 -17
  64. package/packages/config/dist/index.cjs.map +1 -1
  65. package/packages/config/src/index.ts +0 -17
  66. package/packages/rpc/.turbo/turbo-build.log +11 -11
  67. package/packages/rpc/dist/index.cjs +0 -17
  68. package/packages/rpc/dist/index.cjs.map +1 -1
  69. package/packages/rpc/src/index.js +1 -0
  70. package/packages/ui/node_modules/.bin/tsc +2 -2
  71. package/packages/ui/node_modules/.bin/tsserver +2 -2
  72. package/packages/ui/node_modules/.bin/tsup +2 -2
  73. package/packages/ui/node_modules/.bin/tsup-node +2 -2
  74. package/scripts/install-cli-launcher.mjs +37 -0
  75. package/scripts/install-rust-binaries.mjs +47 -0
  76. package/scripts/run-tests-isolated.mjs +210 -0
  77. package/src/cli.ts +310 -50
  78. package/src/lib/admin-reset.ts +15 -30
  79. package/src/lib/admin-setup.ts +246 -55
  80. package/src/lib/agent-auth-migrate.ts +5 -1
  81. package/src/lib/asset-broadcast.ts +15 -4
  82. package/src/lib/config-amounts.ts +6 -4
  83. package/src/lib/hidden-tty-prompt.js +1 -0
  84. package/src/lib/hidden-tty-prompt.ts +105 -0
  85. package/src/lib/keychain.ts +1 -0
  86. package/src/lib/local-admin-access.ts +4 -29
  87. package/src/lib/rust.ts +129 -33
  88. package/src/lib/signed-tx.ts +1 -0
  89. package/src/lib/sudo.ts +15 -5
  90. package/src/lib/wallet-profile.ts +3 -0
  91. package/src/lib/wallet-setup.ts +52 -0
  92. package/packages/cache/dist/chunk-QF4XKEIA.cjs.map +0 -1
  93. package/packages/cache/dist/chunk-QNK6GOTI.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport interface WlfiConfig {\n rpcUrl?: string;\n chainId?: number;\n chainName?: string;\n daemonSocket?: string;\n stateFile?: string;\n rustBinDir?: string;\n agentKeyId?: string;\n agentAuthToken?: string;\n wallet?: WalletProfile;\n chains?: Record<string, ChainProfile>;\n tokens?: Record<string, TokenProfile>;\n}\n\nexport interface WalletProfile {\n vaultKeyId?: string;\n vaultPublicKey: string;\n address?: string;\n agentKeyId?: string;\n policyAttachment: string;\n attachedPolicyIds?: string[];\n policyNote?: string;\n networkScope?: string;\n assetScope?: string;\n recipientScope?: string;\n}\n\nexport interface ChainProfile {\n chainId: number;\n name: string;\n rpcUrl?: string;\n}\n\nexport interface TokenPolicyProfile {\n perTxAmount?: number;\n dailyAmount?: number;\n weeklyAmount?: number;\n perTxAmountDecimal?: string;\n dailyAmountDecimal?: string;\n weeklyAmountDecimal?: string;\n perTxLimit?: string;\n dailyLimit?: string;\n weeklyLimit?: string;\n maxGasPerChainWei?: string;\n dailyMaxTxCount?: string;\n perTxMaxFeePerGasGwei?: string;\n perTxMaxFeePerGasWei?: string;\n perTxMaxPriorityFeePerGasWei?: string;\n perTxMaxCalldataBytes?: string;\n}\n\nexport interface TokenDestinationOverrideProfile {\n recipient: string;\n limits: TokenPolicyProfile;\n}\n\nexport interface TokenManualApprovalProfile {\n priority?: number;\n recipient?: string;\n minAmount?: number;\n maxAmount?: number;\n minAmountDecimal?: string;\n maxAmountDecimal?: string;\n minAmountWei?: string;\n maxAmountWei?: string;\n}\n\nexport interface TokenChainProfile {\n chainId: number;\n isNative: boolean;\n address?: string;\n decimals: number;\n defaultPolicy?: TokenPolicyProfile;\n}\n\nexport interface TokenProfile {\n name?: string;\n symbol: string;\n defaultPolicy?: TokenPolicyProfile;\n destinationOverrides?: TokenDestinationOverrideProfile[];\n manualApprovalPolicies?: TokenManualApprovalProfile[];\n chains: Record<string, TokenChainProfile>;\n}\n\nexport interface TokenChainProfileEntry extends TokenChainProfile {\n key: string;\n}\n\nexport interface TokenProfileEntry {\n key: string;\n name?: string;\n symbol: string;\n chains: TokenChainProfileEntry[];\n}\n\nexport const WLFI_DIRNAME = '.wlfi_agent';\nexport const CONFIG_FILENAME = 'config.json';\n\nconst PRIVATE_DIR_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst GROUP_OTHER_WRITE_MODE_MASK = 0o022;\nconst PRIVATE_FILE_MODE_MASK = 0o077;\nconst STICKY_BIT_MODE = 0o1000;\nconst MAX_CONFIG_FILE_BYTES = 256 * 1024;\nconst DEFAULT_ETH_RPC_URL = 'https://eth.llamarpc.com';\nconst DEFAULT_BSC_RPC_URL = 'https://bsc.drpc.org';\nconst DEFAULT_USD1_ADDRESS = '0xc83DE66ebA6a91B6F3d167f2ee9F0C42aD70B611';\n\nexport const BUILTIN_CHAINS: Record<string, ChainProfile> = {\n eth: { chainId: 1, name: 'eth', rpcUrl: DEFAULT_ETH_RPC_URL },\n ethereum: { chainId: 1, name: 'ethereum', rpcUrl: DEFAULT_ETH_RPC_URL },\n mainnet: { chainId: 1, name: 'mainnet', rpcUrl: DEFAULT_ETH_RPC_URL },\n sepolia: { chainId: 11155111, name: 'sepolia' },\n base: { chainId: 8453, name: 'base' },\n 'base-sepolia': { chainId: 84532, name: 'base-sepolia' },\n optimism: { chainId: 10, name: 'optimism' },\n arbitrum: { chainId: 42161, name: 'arbitrum' },\n polygon: { chainId: 137, name: 'polygon' },\n bsc: { chainId: 56, name: 'bsc', rpcUrl: DEFAULT_BSC_RPC_URL }\n};\n\nexport const BUILTIN_TOKENS: Record<string, TokenProfile> = {\n bnb: {\n name: 'BNB',\n symbol: 'BNB',\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n chains: {\n bsc: {\n chainId: 56,\n isNative: true,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n },\n },\n },\n eth: {\n symbol: 'ETH',\n chains: {\n ethereum: { chainId: 1, isNative: true, decimals: 18 },\n sepolia: { chainId: 11155111, isNative: true, decimals: 18 },\n base: { chainId: 8453, isNative: true, decimals: 18 },\n 'base-sepolia': { chainId: 84532, isNative: true, decimals: 18 },\n optimism: { chainId: 10, isNative: true, decimals: 18 },\n arbitrum: { chainId: 42161, isNative: true, decimals: 18 },\n },\n },\n usdc: {\n symbol: 'USDC',\n chains: {\n ethereum: {\n chainId: 1,\n isNative: false,\n address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',\n decimals: 6,\n },\n base: {\n chainId: 8453,\n isNative: false,\n address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',\n decimals: 6,\n },\n },\n },\n usd1: {\n name: 'USD1',\n symbol: 'USD1',\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n chains: {\n eth: {\n chainId: 1,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n bsc: {\n chainId: 56,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n },\n },\n};\n\nfunction defaultTokenPolicy(perTxAmountDecimal: string, dailyAmountDecimal: string, weeklyAmountDecimal: string): TokenPolicyProfile {\n return {\n perTxAmountDecimal,\n dailyAmountDecimal,\n weeklyAmountDecimal,\n };\n}\n\nfunction defaultChainProfiles(): Record<string, ChainProfile> {\n return {\n eth: {\n chainId: 1,\n name: 'ETH',\n rpcUrl: DEFAULT_ETH_RPC_URL,\n },\n bsc: {\n chainId: 56,\n name: 'BSC',\n rpcUrl: DEFAULT_BSC_RPC_URL,\n },\n };\n}\n\nfunction defaultTokenProfiles(): Record<string, TokenProfile> {\n return {\n usd1: {\n name: 'USD1',\n symbol: 'USD1',\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n destinationOverrides: [],\n manualApprovalPolicies: [],\n chains: {\n eth: {\n chainId: 1,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n bsc: {\n chainId: 56,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n },\n },\n bnb: {\n name: 'BNB',\n symbol: 'BNB',\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n destinationOverrides: [],\n manualApprovalPolicies: [],\n chains: {\n bsc: {\n chainId: 56,\n isNative: true,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n },\n },\n },\n };\n}\n\n\nfunction normalizeLoopbackHostname(hostname: string): string {\n if (hostname.startsWith('[') && hostname.endsWith(']')) {\n return hostname.slice(1, -1).toLowerCase();\n }\n\n return hostname.toLowerCase();\n}\n\nfunction isIpv4Loopback(hostname: string): boolean {\n const parts = hostname.split('.');\n if (parts.length !== 4 || parts.some((part) => !/^\\d+$/u.test(part))) {\n return false;\n }\n\n const octets = parts.map((part) => Number(part));\n if (octets.some((octet) => octet < 0 || octet > 255)) {\n return false;\n }\n\n return octets[0] === 127;\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n const normalized = normalizeLoopbackHostname(hostname);\n return normalized === 'localhost'\n || normalized.endsWith('.localhost')\n || normalized === '::1'\n || isIpv4Loopback(normalized);\n}\n\nexport function assertSafeRpcUrl(value: string, label = 'rpcUrl'): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n\n let parsed: URL;\n try {\n parsed = new URL(normalized);\n } catch {\n throw new Error(`${label} must be a valid http(s) URL`);\n }\n\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n throw new Error(`${label} must use https or localhost http`);\n }\n if (parsed.username || parsed.password) {\n throw new Error(`${label} must not include embedded credentials`);\n }\n if (!parsed.hostname) {\n throw new Error(`${label} must include a hostname`);\n }\n if (parsed.protocol === 'http:' && !isLoopbackHostname(parsed.hostname)) {\n throw new Error(`${label} must use https unless it targets localhost or a loopback address`);\n }\n\n return normalized;\n}\n\nconst ADDRESS_PATTERN = /^0x[a-f0-9]{40}$/iu;\n\nfunction assertValidEvmAddress(value: string, label: string): string {\n const normalized = value.trim();\n if (!ADDRESS_PATTERN.test(normalized)) {\n throw new Error(`${label} must be a valid EVM address`);\n }\n return normalized;\n}\n\nfunction assertPositiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`${label} must be a positive safe integer`);\n }\n return value;\n}\n\nfunction assertTokenDecimals(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 255) {\n throw new Error(`${label} must be an integer between 0 and 255`);\n }\n return value;\n}\n\nfunction assertOptionalTokenAmount(value: number | null | undefined, label: string): number | undefined {\n if (value == null) {\n return undefined;\n }\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n throw new Error(`${label} must be a positive finite number`);\n }\n return value;\n}\n\nfunction assertOptionalTrimmedString(value: string | null | undefined, label: string): string | undefined {\n if (value == null) {\n return undefined;\n }\n const normalized = value.trim();\n if (!normalized) {\n return undefined;\n }\n return normalized;\n}\n\nfunction assertRequiredTrimmedString(value: string | null | undefined, label: string): string {\n const normalized = assertOptionalTrimmedString(value, label);\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n return normalized;\n}\n\nfunction assertOptionalStringArray(value: string[] | null | undefined, label: string): string[] | undefined {\n if (value == null) {\n return undefined;\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {\n throw new Error(`${label} must be an array of strings`);\n }\n const normalized = value\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction normalizeWalletProfile(profile: WalletProfile | null | undefined): WalletProfile | undefined {\n if (profile == null) {\n return undefined;\n }\n\n return {\n vaultKeyId: assertOptionalTrimmedString(profile.vaultKeyId, 'wallet.vaultKeyId'),\n vaultPublicKey: assertRequiredTrimmedString(profile.vaultPublicKey, 'wallet.vaultPublicKey'),\n address: profile.address\n ? assertValidEvmAddress(profile.address, 'wallet.address')\n : undefined,\n agentKeyId: assertOptionalTrimmedString(profile.agentKeyId, 'wallet.agentKeyId'),\n policyAttachment: assertRequiredTrimmedString(profile.policyAttachment, 'wallet.policyAttachment'),\n attachedPolicyIds: assertOptionalStringArray(profile.attachedPolicyIds, 'wallet.attachedPolicyIds'),\n policyNote: assertOptionalTrimmedString(profile.policyNote, 'wallet.policyNote'),\n networkScope: assertOptionalTrimmedString(profile.networkScope, 'wallet.networkScope'),\n assetScope: assertOptionalTrimmedString(profile.assetScope, 'wallet.assetScope'),\n recipientScope: assertOptionalTrimmedString(profile.recipientScope, 'wallet.recipientScope'),\n };\n}\n\nfunction normalizeTokenPolicyProfile(tokenKey: string, chainKey: string, policy: TokenPolicyProfile | undefined) {\n if (!policy) {\n return undefined;\n }\n return {\n perTxAmount: assertOptionalTokenAmount(policy.perTxAmount, `token '${tokenKey}' chain '${chainKey}' perTxAmount`),\n dailyAmount: assertOptionalTokenAmount(policy.dailyAmount, `token '${tokenKey}' chain '${chainKey}' dailyAmount`),\n weeklyAmount: assertOptionalTokenAmount(policy.weeklyAmount, `token '${tokenKey}' chain '${chainKey}' weeklyAmount`),\n perTxAmountDecimal: assertOptionalTrimmedString(policy.perTxAmountDecimal, `token '${tokenKey}' chain '${chainKey}' perTxAmountDecimal`),\n dailyAmountDecimal: assertOptionalTrimmedString(policy.dailyAmountDecimal, `token '${tokenKey}' chain '${chainKey}' dailyAmountDecimal`),\n weeklyAmountDecimal: assertOptionalTrimmedString(policy.weeklyAmountDecimal, `token '${tokenKey}' chain '${chainKey}' weeklyAmountDecimal`),\n perTxLimit: assertOptionalTrimmedString(policy.perTxLimit, `token '${tokenKey}' chain '${chainKey}' perTxLimit`),\n dailyLimit: assertOptionalTrimmedString(policy.dailyLimit, `token '${tokenKey}' chain '${chainKey}' dailyLimit`),\n weeklyLimit: assertOptionalTrimmedString(policy.weeklyLimit, `token '${tokenKey}' chain '${chainKey}' weeklyLimit`),\n maxGasPerChainWei: assertOptionalTrimmedString(policy.maxGasPerChainWei, `token '${tokenKey}' chain '${chainKey}' maxGasPerChainWei`),\n dailyMaxTxCount: assertOptionalTrimmedString(policy.dailyMaxTxCount, `token '${tokenKey}' chain '${chainKey}' dailyMaxTxCount`),\n perTxMaxFeePerGasGwei: assertOptionalTrimmedString(policy.perTxMaxFeePerGasGwei, `token '${tokenKey}' chain '${chainKey}' perTxMaxFeePerGasGwei`),\n perTxMaxFeePerGasWei: assertOptionalTrimmedString(policy.perTxMaxFeePerGasWei, `token '${tokenKey}' chain '${chainKey}' perTxMaxFeePerGasWei`),\n perTxMaxPriorityFeePerGasWei: assertOptionalTrimmedString(policy.perTxMaxPriorityFeePerGasWei, `token '${tokenKey}' chain '${chainKey}' perTxMaxPriorityFeePerGasWei`),\n perTxMaxCalldataBytes: assertOptionalTrimmedString(policy.perTxMaxCalldataBytes, `token '${tokenKey}' chain '${chainKey}' perTxMaxCalldataBytes`),\n } satisfies TokenPolicyProfile;\n}\n\nfunction normalizeTokenDestinationOverrideProfile(\n tokenKey: string,\n profile: TokenDestinationOverrideProfile\n): TokenDestinationOverrideProfile {\n const recipient = assertValidEvmAddress(profile.recipient, `token '${tokenKey}' destination override recipient`);\n return {\n recipient,\n limits: normalizeTokenPolicyProfile(tokenKey, 'override', profile.limits) ?? {},\n };\n}\n\nfunction normalizeTokenManualApprovalProfile(\n tokenKey: string,\n profile: TokenManualApprovalProfile\n): TokenManualApprovalProfile {\n return {\n priority: profile.priority === undefined ? undefined : assertPositiveSafeInteger(profile.priority, `token '${tokenKey}' manual approval priority`),\n recipient: profile.recipient\n ? assertValidEvmAddress(profile.recipient, `token '${tokenKey}' manual approval recipient`)\n : undefined,\n minAmount: assertOptionalTokenAmount(profile.minAmount, `token '${tokenKey}' manual approval minAmount`),\n maxAmount: assertOptionalTokenAmount(profile.maxAmount, `token '${tokenKey}' manual approval maxAmount`),\n minAmountDecimal: assertOptionalTrimmedString(profile.minAmountDecimal, `token '${tokenKey}' manual approval minAmountDecimal`),\n maxAmountDecimal: assertOptionalTrimmedString(profile.maxAmountDecimal, `token '${tokenKey}' manual approval maxAmountDecimal`),\n minAmountWei: assertOptionalTrimmedString(profile.minAmountWei, `token '${tokenKey}' manual approval minAmountWei`),\n maxAmountWei: assertOptionalTrimmedString(profile.maxAmountWei, `token '${tokenKey}' manual approval maxAmountWei`),\n };\n}\n\nfunction normalizeTokenChainProfile(tokenKey: string, chainKey: string, profile: TokenChainProfile): TokenChainProfile {\n const normalizedChainKey = chainKey.trim().toLowerCase();\n if (!normalizedChainKey) {\n throw new Error(`token '${tokenKey}' chain key is required`);\n }\n\n const normalized: TokenChainProfile = {\n chainId: assertPositiveSafeInteger(profile.chainId, `token '${tokenKey}' chain '${normalizedChainKey}' chainId`),\n isNative: Boolean(profile.isNative),\n decimals: assertTokenDecimals(profile.decimals, `token '${tokenKey}' chain '${normalizedChainKey}' decimals`),\n defaultPolicy: normalizeTokenPolicyProfile(tokenKey, normalizedChainKey, profile.defaultPolicy),\n };\n\n if (normalized.isNative) {\n if (profile.address?.trim()) {\n throw new Error(`token '${tokenKey}' chain '${normalizedChainKey}' must not set address when isNative=true`);\n }\n } else {\n normalized.address = assertValidEvmAddress(\n profile.address ?? '',\n `token '${tokenKey}' chain '${normalizedChainKey}' address`\n );\n }\n\n return normalized;\n}\n\nfunction normalizeTokenProfile(key: string, profile: TokenProfile): TokenProfile {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('token profile key is required');\n }\n\n const symbol = profile.symbol?.trim();\n if (!symbol) {\n throw new Error(`token profile '${normalizedKey}' symbol is required`);\n }\n const name = assertOptionalTrimmedString(profile.name, `token profile '${normalizedKey}' name`);\n\n const normalizedChains: Record<string, TokenChainProfile> = {};\n for (const [chainKey, chainProfile] of Object.entries(profile.chains ?? {})) {\n const normalizedChainKey = chainKey.trim().toLowerCase();\n if (!normalizedChainKey) {\n throw new Error(`token profile '${normalizedKey}' contains an empty chain key`);\n }\n normalizedChains[normalizedChainKey] = normalizeTokenChainProfile(normalizedKey, normalizedChainKey, chainProfile);\n }\n\n return {\n name,\n symbol,\n defaultPolicy: normalizeTokenPolicyProfile(normalizedKey, 'default', profile.defaultPolicy),\n destinationOverrides: (profile.destinationOverrides ?? []).map((item) =>\n normalizeTokenDestinationOverrideProfile(normalizedKey, item)\n ),\n manualApprovalPolicies: (profile.manualApprovalPolicies ?? []).map((item) =>\n normalizeTokenManualApprovalProfile(normalizedKey, item)\n ),\n chains: normalizedChains,\n };\n}\n\nfunction normalizeChainProfileEntry(key: string, profile: ChainProfile): ChainProfile {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n\n const name = profile.name?.trim() || normalizedKey;\n return {\n chainId: assertPositiveSafeInteger(profile.chainId, `chain profile '${normalizedKey}' chainId`),\n name,\n rpcUrl: profile.rpcUrl\n ? assertSafeRpcUrl(profile.rpcUrl, `chain profile '${normalizedKey}' rpcUrl`)\n : undefined,\n };\n}\n\nfunction normalizeChainProfiles(profiles: Record<string, ChainProfile> | undefined): Record<string, ChainProfile> {\n const normalized: Record<string, ChainProfile> = {};\n for (const [key, profile] of Object.entries(profiles ?? {})) {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n normalized[normalizedKey] = normalizeChainProfileEntry(normalizedKey, profile);\n }\n return normalized;\n}\n\nfunction normalizeTokenProfiles(profiles: Record<string, TokenProfile> | undefined): Record<string, TokenProfile> {\n const normalized: Record<string, TokenProfile> = {};\n for (const [key, profile] of Object.entries(profiles ?? {})) {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('token profile key is required');\n }\n normalized[normalizedKey] = normalizeTokenProfile(normalizedKey, profile);\n }\n return normalized;\n}\n\nfunction normalizePath(targetPath: string): string {\n return path.resolve(targetPath);\n}\n\nfunction requirePathValue(targetPath: string, label: string): string {\n const normalized = targetPath.trim();\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n\n return normalizePath(normalized);\n}\n\nfunction readLstat(targetPath: string): fs.Stats | null {\n try {\n return fs.lstatSync(targetPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\nfunction readLstatAllowInaccessible(targetPath: string): fs.Stats | 'inaccessible' | null {\n try {\n return fs.lstatSync(targetPath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n return null;\n }\n if (code === 'EACCES' || code === 'EPERM') {\n return 'inaccessible';\n }\n throw error;\n }\n}\n\nfunction isStableRootOwnedSymlink(stats: fs.Stats, targetPath: string): boolean {\n if (process.platform === 'win32' || typeof stats.uid !== 'number' || stats.uid !== 0) {\n return false;\n }\n\n const parentPath = path.dirname(targetPath);\n const parentStats = readLstat(parentPath);\n return Boolean(\n parentStats\n && parentStats.isDirectory()\n && typeof parentStats.uid === 'number'\n && parentStats.uid === 0\n && (parentStats.mode & GROUP_OTHER_WRITE_MODE_MASK) === 0\n );\n}\n\nfunction assertNoSymlinkAncestorDirectories(targetPath: string, label: string): void {\n const normalized = normalizePath(targetPath);\n const parent = path.dirname(normalized);\n if (parent === normalized) {\n return;\n }\n\n const { root } = path.parse(parent);\n const relativeParent = parent.slice(root.length);\n if (!relativeParent) {\n return;\n }\n\n let currentPath = root;\n for (const segment of relativeParent.split(path.sep).filter(Boolean)) {\n currentPath = path.join(currentPath, segment);\n const stats = readLstat(currentPath);\n if (!stats) {\n break;\n }\n if (stats.isSymbolicLink()) {\n if (isStableRootOwnedSymlink(stats, currentPath)) {\n continue;\n }\n throw new Error(`${label} '${normalized}' must not traverse symlinked ancestor directories`);\n }\n }\n}\n\nfunction findNearestExistingPath(targetPath: string): { path: string; stats: fs.Stats } {\n let currentPath = normalizePath(targetPath);\n\n while (true) {\n const stats = readLstat(currentPath);\n if (stats) {\n return {\n path: currentPath,\n stats\n };\n }\n\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n throw new Error(`No existing ancestor directory found for '${targetPath}'`);\n }\n\n currentPath = parentPath;\n }\n}\n\nexport function allowedOwnerUids(): Set<number> {\n const allowed = new Set<number>();\n const effectiveUid = typeof process.geteuid === 'function' ? process.geteuid() : null;\n if (effectiveUid !== null) {\n allowed.add(effectiveUid);\n }\n\n const sudoUid = process.env.SUDO_UID?.trim();\n if (effectiveUid === 0 && sudoUid && /^\\d+$/u.test(sudoUid)) {\n allowed.add(Number(sudoUid));\n }\n\n return allowed;\n}\n\nfunction assertTrustedOwner(stats: fs.Stats, targetPath: string, label: string): void {\n if (process.platform === 'win32' || typeof stats.uid !== 'number') {\n return;\n }\n\n if (stats.uid === 0) {\n return;\n }\n\n const allowed = allowedOwnerUids();\n if (!allowed.has(stats.uid)) {\n throw new Error(\n `${label} '${targetPath}' must be owned by the current user, sudo caller, or root`\n );\n }\n}\n\nfunction assertSecureDirectory(stats: fs.Stats, targetPath: string, label: string): void {\n assertTrustedOwner(stats, targetPath, label);\n if (process.platform === 'win32') {\n return;\n }\n\n if ((stats.mode & GROUP_OTHER_WRITE_MODE_MASK) !== 0) {\n throw new Error(`${label} '${targetPath}' must not be writable by group/other`);\n }\n}\n\nfunction isStickyDirectory(stats: fs.Stats): boolean {\n return process.platform !== 'win32' && (stats.mode & STICKY_BIT_MODE) !== 0;\n}\n\nfunction assertSecureDirectoryPath(targetPath: string, label: string): void {\n const normalized = normalizePath(targetPath);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const targetStats = fs.lstatSync(normalized);\n if (targetStats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!targetStats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n\n assertSecureDirectory(targetStats, normalized, label);\n\n const ancestors: string[] = [];\n let currentPath = fs.realpathSync.native(normalized);\n\n while (true) {\n ancestors.push(currentPath);\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n break;\n }\n currentPath = parentPath;\n }\n\n for (const [index, currentDirectory] of ancestors.entries()) {\n if (index === 0) {\n continue;\n }\n\n const stats = fs.lstatSync(currentDirectory);\n if (!stats.isDirectory()) {\n throw new Error(`${label} '${currentDirectory}' must be a directory`);\n }\n\n assertTrustedOwner(stats, currentDirectory, label);\n if (process.platform !== 'win32' && (stats.mode & GROUP_OTHER_WRITE_MODE_MASK) !== 0) {\n const allowStickyAncestor = index > 0 && isStickyDirectory(stats);\n if (!allowStickyAncestor) {\n throw new Error(`${label} '${currentDirectory}' must not be writable by group/other`);\n }\n }\n }\n}\n\nfunction assertSecureFile(stats: fs.Stats, targetPath: string, label: string): void {\n assertTrustedOwner(stats, targetPath, label);\n if (process.platform === 'win32') {\n return;\n }\n\n if ((stats.mode & PRIVATE_FILE_MODE_MASK) !== 0) {\n throw new Error(`${label} '${targetPath}' must not grant group/other permissions`);\n }\n}\n\nfunction assertNotSymlink(targetPath: string, label: string): fs.Stats | null {\n const stats = readLstat(targetPath);\n if (stats?.isSymbolicLink()) {\n throw new Error(`${label} '${targetPath}' must not be a symlink`);\n }\n return stats;\n}\n\nfunction tightenPermissions(targetPath: string, mode: number) {\n try {\n fs.chmodSync(targetPath, mode);\n } catch {}\n}\n\nfunction ensurePrivateDirectory(targetPath: string, label: string): string {\n const normalized = normalizePath(targetPath);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const stats = assertNotSymlink(normalized, label);\n if (stats && !stats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n if (!stats) {\n fs.mkdirSync(normalized, { recursive: true, mode: PRIVATE_DIR_MODE });\n }\n tightenPermissions(normalized, PRIVATE_DIR_MODE);\n assertSecureDirectoryPath(normalized, label);\n return normalized;\n}\n\nfunction readUtf8FileSecure(targetPath: string, label: string, maxBytes?: number): string {\n const normalized = normalizePath(targetPath);\n assertSecureDirectoryPath(path.dirname(normalized), `${label} parent directory`);\n const openFlags = process.platform === 'win32'\n ? fs.constants.O_RDONLY\n : fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n const fd = fs.openSync(normalized, openFlags);\n\n try {\n const stats = fs.fstatSync(fd);\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n assertSecureFile(stats, normalized, label);\n if (maxBytes !== undefined && stats.size > maxBytes) {\n throw new Error(`${label} '${normalized}' must not exceed ${maxBytes} bytes`);\n }\n return fs.readFileSync(fd, 'utf8');\n } finally {\n fs.closeSync(fd);\n }\n}\n\nfunction readPrivateJsonFile<T>(targetPath: string, label: string): T | null {\n const normalized = normalizePath(targetPath);\n const stats = assertNotSymlink(normalized, label);\n if (!stats) {\n return null;\n }\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n tightenPermissions(normalized, PRIVATE_FILE_MODE);\n return JSON.parse(readUtf8FileSecure(normalized, label, MAX_CONFIG_FILE_BYTES)) as T;\n}\n\nfunction assertSecurePlannedDirectoryPath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const stats = readLstat(normalized);\n\n if (stats) {\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!stats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n\n assertSecureDirectoryPath(normalized, label);\n return normalized;\n }\n\n const nearestExistingPath = findNearestExistingPath(normalized);\n if (nearestExistingPath.stats.isSymbolicLink()) {\n throw new Error(`${label} '${nearestExistingPath.path}' must not be a symlink`);\n }\n if (!nearestExistingPath.stats.isDirectory()) {\n throw new Error(`${label} '${nearestExistingPath.path}' must be a directory`);\n }\n\n assertSecureDirectoryPath(nearestExistingPath.path, label);\n return normalized;\n}\n\nfunction assertSecurePlannedDaemonSocketPath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertSecurePlannedDirectoryPath(path.dirname(normalized), `${label} directory`);\n\n const stats = readLstat(normalized);\n if (!stats) {\n return normalized;\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (process.platform !== 'win32' && !stats.isSocket()) {\n throw new Error(`${label} '${normalized}' must be a unix socket`);\n }\n\n assertTrustedOwner(stats, normalized, label);\n return normalized;\n}\n\nfunction assertSecurePlannedPrivateFilePath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertSecurePlannedDirectoryPath(path.dirname(normalized), `${label} directory`);\n\n const stats = readLstatAllowInaccessible(normalized);\n if (!stats || stats === 'inaccessible') {\n return normalized;\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n\n assertSecureFile(stats, normalized, label);\n return normalized;\n}\n\nfunction writePrivateFile(targetPath: string, contents: string, label: string) {\n const normalized = normalizePath(targetPath);\n const parent = ensurePrivateDirectory(path.dirname(normalized), `${label} parent`);\n assertNotSymlink(normalized, label);\n\n const tempPath = path.join(\n parent,\n `.${path.basename(normalized)}.tmp-${process.pid}-${Date.now()}`\n );\n\n try {\n fs.writeFileSync(tempPath, contents, {\n encoding: 'utf8',\n mode: PRIVATE_FILE_MODE,\n flag: 'wx'\n });\n tightenPermissions(tempPath, PRIVATE_FILE_MODE);\n fs.renameSync(tempPath, normalized);\n tightenPermissions(normalized, PRIVATE_FILE_MODE);\n } finally {\n try {\n if (fs.existsSync(tempPath)) {\n fs.rmSync(tempPath);\n }\n } catch {}\n }\n}\n\nfunction normalizedDefaultConfig(): WlfiConfig {\n return {\n daemonSocket: defaultDaemonSocketPath(),\n stateFile: defaultStateFilePath(),\n rustBinDir: defaultRustBinDir(),\n chains: defaultChainProfiles(),\n tokens: defaultTokenProfiles()\n };\n}\n\nfunction applySeedDefaultsIfLegacyEmpty(config: WlfiConfig): WlfiConfig {\n const chainCount = Object.keys(config.chains ?? {}).length;\n const tokenCount = Object.keys(config.tokens ?? {}).length;\n if (chainCount === 0 && tokenCount === 0) {\n return {\n ...config,\n chains: defaultChainProfiles(),\n tokens: defaultTokenProfiles(),\n };\n }\n return config;\n}\n\nexport function resolveWlfiHome(): string {\n const explicit = process.env.WLFI_HOME?.trim();\n if (explicit) {\n return normalizePath(explicit);\n }\n return path.join(os.homedir(), WLFI_DIRNAME);\n}\n\nexport function resolveConfigPath(): string {\n return path.join(resolveWlfiHome(), CONFIG_FILENAME);\n}\n\nexport function defaultDaemonSocketPath(): string {\n return path.join(resolveWlfiHome(), 'daemon.sock');\n}\n\nexport function defaultStateFilePath(): string {\n return path.join(resolveWlfiHome(), 'daemon-state.enc');\n}\n\nexport function defaultRustBinDir(): string {\n return path.join(resolveWlfiHome(), 'bin');\n}\n\nexport function defaultConfig(): WlfiConfig {\n return normalizedDefaultConfig();\n}\n\nexport function ensureWlfiHome(): string {\n return ensurePrivateDirectory(resolveWlfiHome(), 'WLFI home');\n}\n\nexport function readConfig(): WlfiConfig {\n ensureWlfiHome();\n const parsed = readPrivateJsonFile<WlfiConfig>(resolveConfigPath(), 'config file');\n const merged = applySeedDefaultsIfLegacyEmpty({\n ...normalizedDefaultConfig(),\n ...(parsed ?? {})\n } satisfies WlfiConfig);\n\n return {\n ...merged,\n wallet: normalizeWalletProfile(merged.wallet),\n chains: normalizeChainProfiles(merged.chains),\n tokens: normalizeTokenProfiles(merged.tokens),\n };\n}\n\nexport function writeConfig(nextConfig: WlfiConfig): WlfiConfig {\n ensureWlfiHome();\n const merged: WlfiConfig = {\n ...normalizedDefaultConfig(),\n ...readConfig(),\n ...nextConfig\n };\n\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'rpcUrl') && merged.rpcUrl !== undefined) {\n merged.rpcUrl = assertSafeRpcUrl(merged.rpcUrl, 'rpcUrl');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'daemonSocket') && merged.daemonSocket !== undefined) {\n merged.daemonSocket = assertSecurePlannedDaemonSocketPath(merged.daemonSocket, 'daemonSocket');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'stateFile') && merged.stateFile !== undefined) {\n merged.stateFile = assertSecurePlannedPrivateFilePath(merged.stateFile, 'stateFile');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'rustBinDir') && merged.rustBinDir !== undefined) {\n merged.rustBinDir = assertSecurePlannedDirectoryPath(merged.rustBinDir, 'rustBinDir');\n }\n\n merged.wallet = normalizeWalletProfile(merged.wallet);\n merged.chains = normalizeChainProfiles(merged.chains);\n merged.tokens = normalizeTokenProfiles(merged.tokens);\n\n writePrivateFile(resolveConfigPath(), JSON.stringify(merged, null, 2) + '\\n', 'config file');\n return merged;\n}\n\nexport function deleteConfigKey(key: keyof WlfiConfig): WlfiConfig {\n ensureWlfiHome();\n const current = {\n ...normalizedDefaultConfig(),\n ...readConfig()\n };\n delete current[key];\n\n const normalized = {\n ...normalizedDefaultConfig(),\n ...current,\n chains: current.chains ?? {},\n tokens: current.tokens ?? {}\n };\n\n writePrivateFile(resolveConfigPath(), JSON.stringify(normalized, null, 2) + '\\n', 'config file');\n return normalized;\n}\n\nexport function listBuiltinChains(): ChainProfile[] {\n return Object.entries(BUILTIN_CHAINS)\n .map(([key, value]) => ({ ...value, name: key }))\n .sort((left, right) => left.chainId - right.chainId || left.name.localeCompare(right.name));\n}\n\nexport function listBuiltinTokens(): TokenProfileEntry[] {\n return Object.entries(BUILTIN_TOKENS)\n .map(([key, value]) => ({\n key,\n name: value.name,\n symbol: value.symbol,\n chains: Object.entries(value.chains ?? {})\n .map(([chainKey, chainValue]) => ({ key: chainKey, ...chainValue }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key)),\n }))\n .sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport function listConfiguredTokens(\n config: WlfiConfig = readConfig()\n): TokenProfileEntry[] {\n return Object.entries(config.tokens ?? {})\n .map(([key, value]) => ({\n key,\n name: value.name,\n symbol: value.symbol,\n chains: Object.entries(value.chains ?? {})\n .map(([chainKey, chainValue]) => ({ key: chainKey, ...chainValue }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key)),\n }))\n .sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport function resolveTokenProfile(\n selector: string,\n config: WlfiConfig = readConfig()\n): (TokenProfile & { key: string; source: 'configured' | 'builtin' }) | null {\n const normalized = selector.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n for (const [key, value] of Object.entries(config.tokens ?? {})) {\n if (key.toLowerCase() === normalized || value.symbol.toLowerCase() === normalized) {\n return { key, source: 'configured', ...value };\n }\n }\n\n for (const [key, value] of Object.entries(BUILTIN_TOKENS)) {\n if (key.toLowerCase() === normalized || value.symbol.toLowerCase() === normalized) {\n return { key, source: 'builtin', ...value };\n }\n }\n\n return null;\n}\n\nexport function listConfiguredChains(config: WlfiConfig = readConfig()): Array<ChainProfile & { key: string }> {\n return Object.entries(config.chains ?? {})\n .map(([key, value]) => ({ key, ...value }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key));\n}\n\nexport function resolveChainProfile(selector: string, config: WlfiConfig = readConfig()): (ChainProfile & { key?: string; source: 'configured' | 'builtin' | 'active' }) | null {\n const normalized = selector.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n for (const [key, value] of Object.entries(config.chains ?? {})) {\n if (key.toLowerCase() === normalized || value.name.toLowerCase() === normalized || String(value.chainId) === selector) {\n return { ...value, key, source: 'configured' };\n }\n }\n\n if (BUILTIN_CHAINS[normalized]) {\n return { ...BUILTIN_CHAINS[normalized], key: normalized, source: 'builtin' };\n }\n\n if (config.chainId !== undefined && String(config.chainId) === selector) {\n return {\n chainId: config.chainId,\n name: config.chainName ?? normalized,\n rpcUrl: config.rpcUrl,\n source: 'active'\n };\n }\n\n return null;\n}\n\nexport function saveChainProfile(key: string, profile: ChainProfile): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n\n const normalizedProfile = normalizeChainProfileEntry(normalizedKey, profile);\n\n return writeConfig({\n chains: {\n ...(readConfig().chains ?? {}),\n [normalizedKey]: normalizedProfile\n }\n });\n}\n\nexport function removeChainProfile(key: string): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n const nextChains = { ...(readConfig().chains ?? {}) };\n delete nextChains[normalizedKey];\n return writeConfig({ chains: nextChains });\n}\n\nexport function saveTokenProfile(key: string, profile: TokenProfile): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n return writeConfig({\n tokens: {\n ...(readConfig().tokens ?? {}),\n [normalizedKey]: normalizeTokenProfile(normalizedKey, profile),\n },\n });\n}\n\nexport function saveTokenChainProfile(\n tokenKey: string,\n chainKey: string,\n profile: TokenChainProfile,\n options: { symbol?: string } = {}\n): WlfiConfig {\n const normalizedTokenKey = tokenKey.trim().toLowerCase();\n const normalizedChainKey = chainKey.trim().toLowerCase();\n const current = readConfig();\n const existing = current.tokens?.[normalizedTokenKey];\n const symbol = options.symbol?.trim() || existing?.symbol;\n if (!symbol) {\n throw new Error(`token '${normalizedTokenKey}' symbol is required`);\n }\n\n return writeConfig({\n tokens: {\n ...(current.tokens ?? {}),\n [normalizedTokenKey]: normalizeTokenProfile(normalizedTokenKey, {\n name: existing?.name,\n symbol,\n defaultPolicy: existing?.defaultPolicy,\n destinationOverrides: existing?.destinationOverrides,\n manualApprovalPolicies: existing?.manualApprovalPolicies,\n chains: {\n ...(existing?.chains ?? {}),\n [normalizedChainKey]: normalizeTokenChainProfile(normalizedTokenKey, normalizedChainKey, profile),\n },\n }),\n },\n });\n}\n\nexport function removeTokenProfile(key: string): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n const nextTokens = { ...(readConfig().tokens ?? {}) };\n delete nextTokens[normalizedKey];\n return writeConfig({ tokens: nextTokens });\n}\n\nexport function removeTokenChainProfile(tokenKey: string, chainKey: string): WlfiConfig {\n const normalizedTokenKey = tokenKey.trim().toLowerCase();\n const normalizedChainKey = chainKey.trim().toLowerCase();\n const current = readConfig();\n const token = current.tokens?.[normalizedTokenKey];\n if (!token) {\n return current;\n }\n\n const nextChains = { ...(token.chains ?? {}) };\n delete nextChains[normalizedChainKey];\n const nextTokens = { ...(current.tokens ?? {}) };\n if (Object.keys(nextChains).length === 0) {\n delete nextTokens[normalizedTokenKey];\n } else {\n nextTokens[normalizedTokenKey] = normalizeTokenProfile(normalizedTokenKey, {\n name: token.name,\n symbol: token.symbol,\n defaultPolicy: token.defaultPolicy,\n destinationOverrides: token.destinationOverrides,\n manualApprovalPolicies: token.manualApprovalPolicies,\n chains: nextChains,\n });\n }\n return writeConfig({ tokens: nextTokens });\n}\n\nexport function switchActiveChain(selector: string, options: { rpcUrl?: string; persistProfile?: boolean } = {}): WlfiConfig {\n const config = readConfig();\n const profile = resolveChainProfile(selector, config);\n if (!profile) {\n throw new Error(`Unknown chain selector: ${selector}`);\n }\n\n const nextRpcUrl = options.rpcUrl ?? profile.rpcUrl;\n const normalizedRpcUrl = nextRpcUrl ? assertSafeRpcUrl(nextRpcUrl, 'rpcUrl') : undefined;\n let next = writeConfig({\n chainId: profile.chainId,\n chainName: profile.name,\n rpcUrl: normalizedRpcUrl,\n chains: config.chains ?? {}\n });\n\n if (options.persistProfile) {\n next = saveChainProfile(profile.key ?? profile.name, {\n chainId: profile.chainId,\n name: profile.name,\n rpcUrl: normalizedRpcUrl\n });\n }\n\n return next;\n}\n\nexport function redactConfig(config: WlfiConfig): Record<string, unknown> {\n return {\n ...config,\n agentAuthToken: config.agentAuthToken ? '<redacted>' : undefined,\n paths: {\n wlfiHome: resolveWlfiHome(),\n configPath: resolveConfigPath(),\n daemonSocket: config.daemonSocket ?? defaultDaemonSocketPath(),\n stateFile: config.stateFile ?? defaultStateFilePath(),\n rustBinDir: config.rustBinDir ?? defaultRustBinDir()\n }\n };\n}\n\nexport function resolveRustBinaryPath(binaryName: string, config: WlfiConfig = readConfig()): string {\n return path.join(config.rustBinDir ?? defaultRustBinDir(), binaryName + (process.platform === 'win32' ? '.exe' : ''));\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nexport interface WlfiConfig {\n rpcUrl?: string;\n chainId?: number;\n chainName?: string;\n daemonSocket?: string;\n stateFile?: string;\n rustBinDir?: string;\n agentKeyId?: string;\n agentAuthToken?: string;\n wallet?: WalletProfile;\n chains?: Record<string, ChainProfile>;\n tokens?: Record<string, TokenProfile>;\n}\n\nexport interface WalletProfile {\n vaultKeyId?: string;\n vaultPublicKey: string;\n address?: string;\n agentKeyId?: string;\n policyAttachment: string;\n attachedPolicyIds?: string[];\n policyNote?: string;\n networkScope?: string;\n assetScope?: string;\n recipientScope?: string;\n}\n\nexport interface ChainProfile {\n chainId: number;\n name: string;\n rpcUrl?: string;\n}\n\nexport interface TokenPolicyProfile {\n perTxAmount?: number;\n dailyAmount?: number;\n weeklyAmount?: number;\n perTxAmountDecimal?: string;\n dailyAmountDecimal?: string;\n weeklyAmountDecimal?: string;\n perTxLimit?: string;\n dailyLimit?: string;\n weeklyLimit?: string;\n maxGasPerChainWei?: string;\n dailyMaxTxCount?: string;\n perTxMaxFeePerGasGwei?: string;\n perTxMaxFeePerGasWei?: string;\n perTxMaxPriorityFeePerGasWei?: string;\n perTxMaxCalldataBytes?: string;\n}\n\nexport interface TokenDestinationOverrideProfile {\n recipient: string;\n limits: TokenPolicyProfile;\n}\n\nexport interface TokenManualApprovalProfile {\n priority?: number;\n recipient?: string;\n minAmount?: number;\n maxAmount?: number;\n minAmountDecimal?: string;\n maxAmountDecimal?: string;\n minAmountWei?: string;\n maxAmountWei?: string;\n}\n\nexport interface TokenChainProfile {\n chainId: number;\n isNative: boolean;\n address?: string;\n decimals: number;\n defaultPolicy?: TokenPolicyProfile;\n}\n\nexport interface TokenProfile {\n name?: string;\n symbol: string;\n defaultPolicy?: TokenPolicyProfile;\n destinationOverrides?: TokenDestinationOverrideProfile[];\n manualApprovalPolicies?: TokenManualApprovalProfile[];\n chains: Record<string, TokenChainProfile>;\n}\n\nexport interface TokenChainProfileEntry extends TokenChainProfile {\n key: string;\n}\n\nexport interface TokenProfileEntry {\n key: string;\n name?: string;\n symbol: string;\n chains: TokenChainProfileEntry[];\n}\n\nexport const WLFI_DIRNAME = '.wlfi_agent';\nexport const CONFIG_FILENAME = 'config.json';\n\nconst PRIVATE_DIR_MODE = 0o700;\nconst PRIVATE_FILE_MODE = 0o600;\nconst GROUP_OTHER_WRITE_MODE_MASK = 0o022;\nconst PRIVATE_FILE_MODE_MASK = 0o077;\nconst STICKY_BIT_MODE = 0o1000;\nconst MAX_CONFIG_FILE_BYTES = 256 * 1024;\nconst DEFAULT_ETH_RPC_URL = 'https://eth.llamarpc.com';\nconst DEFAULT_BSC_RPC_URL = 'https://bsc.drpc.org';\nconst DEFAULT_USD1_ADDRESS = '0xc83DE66ebA6a91B6F3d167f2ee9F0C42aD70B611';\n\nexport const BUILTIN_CHAINS: Record<string, ChainProfile> = {\n eth: { chainId: 1, name: 'eth', rpcUrl: DEFAULT_ETH_RPC_URL },\n ethereum: { chainId: 1, name: 'ethereum', rpcUrl: DEFAULT_ETH_RPC_URL },\n mainnet: { chainId: 1, name: 'mainnet', rpcUrl: DEFAULT_ETH_RPC_URL },\n sepolia: { chainId: 11155111, name: 'sepolia' },\n base: { chainId: 8453, name: 'base' },\n 'base-sepolia': { chainId: 84532, name: 'base-sepolia' },\n optimism: { chainId: 10, name: 'optimism' },\n arbitrum: { chainId: 42161, name: 'arbitrum' },\n polygon: { chainId: 137, name: 'polygon' },\n bsc: { chainId: 56, name: 'bsc', rpcUrl: DEFAULT_BSC_RPC_URL }\n};\n\nexport const BUILTIN_TOKENS: Record<string, TokenProfile> = {\n bnb: {\n name: 'BNB',\n symbol: 'BNB',\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n chains: {\n bsc: {\n chainId: 56,\n isNative: true,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n },\n },\n },\n eth: {\n symbol: 'ETH',\n chains: {\n ethereum: { chainId: 1, isNative: true, decimals: 18 },\n sepolia: { chainId: 11155111, isNative: true, decimals: 18 },\n base: { chainId: 8453, isNative: true, decimals: 18 },\n 'base-sepolia': { chainId: 84532, isNative: true, decimals: 18 },\n optimism: { chainId: 10, isNative: true, decimals: 18 },\n arbitrum: { chainId: 42161, isNative: true, decimals: 18 },\n },\n },\n usd1: {\n name: 'USD1',\n symbol: 'USD1',\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n chains: {\n eth: {\n chainId: 1,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n bsc: {\n chainId: 56,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n },\n },\n};\n\nfunction defaultTokenPolicy(perTxAmountDecimal: string, dailyAmountDecimal: string, weeklyAmountDecimal: string): TokenPolicyProfile {\n return {\n perTxAmountDecimal,\n dailyAmountDecimal,\n weeklyAmountDecimal,\n };\n}\n\nfunction defaultChainProfiles(): Record<string, ChainProfile> {\n return {\n eth: {\n chainId: 1,\n name: 'ETH',\n rpcUrl: DEFAULT_ETH_RPC_URL,\n },\n bsc: {\n chainId: 56,\n name: 'BSC',\n rpcUrl: DEFAULT_BSC_RPC_URL,\n },\n };\n}\n\nfunction defaultTokenProfiles(): Record<string, TokenProfile> {\n return {\n usd1: {\n name: 'USD1',\n symbol: 'USD1',\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n destinationOverrides: [],\n manualApprovalPolicies: [],\n chains: {\n eth: {\n chainId: 1,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n bsc: {\n chainId: 56,\n isNative: false,\n address: DEFAULT_USD1_ADDRESS,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('10', '100', '700'),\n },\n },\n },\n bnb: {\n name: 'BNB',\n symbol: 'BNB',\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n destinationOverrides: [],\n manualApprovalPolicies: [],\n chains: {\n bsc: {\n chainId: 56,\n isNative: true,\n decimals: 18,\n defaultPolicy: defaultTokenPolicy('0.01', '0.2', '1.4'),\n },\n },\n },\n };\n}\n\n\nfunction normalizeLoopbackHostname(hostname: string): string {\n if (hostname.startsWith('[') && hostname.endsWith(']')) {\n return hostname.slice(1, -1).toLowerCase();\n }\n\n return hostname.toLowerCase();\n}\n\nfunction isIpv4Loopback(hostname: string): boolean {\n const parts = hostname.split('.');\n if (parts.length !== 4 || parts.some((part) => !/^\\d+$/u.test(part))) {\n return false;\n }\n\n const octets = parts.map((part) => Number(part));\n if (octets.some((octet) => octet < 0 || octet > 255)) {\n return false;\n }\n\n return octets[0] === 127;\n}\n\nfunction isLoopbackHostname(hostname: string): boolean {\n const normalized = normalizeLoopbackHostname(hostname);\n return normalized === 'localhost'\n || normalized.endsWith('.localhost')\n || normalized === '::1'\n || isIpv4Loopback(normalized);\n}\n\nexport function assertSafeRpcUrl(value: string, label = 'rpcUrl'): string {\n const normalized = value.trim();\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n\n let parsed: URL;\n try {\n parsed = new URL(normalized);\n } catch {\n throw new Error(`${label} must be a valid http(s) URL`);\n }\n\n if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {\n throw new Error(`${label} must use https or localhost http`);\n }\n if (parsed.username || parsed.password) {\n throw new Error(`${label} must not include embedded credentials`);\n }\n if (!parsed.hostname) {\n throw new Error(`${label} must include a hostname`);\n }\n if (parsed.protocol === 'http:' && !isLoopbackHostname(parsed.hostname)) {\n throw new Error(`${label} must use https unless it targets localhost or a loopback address`);\n }\n\n return normalized;\n}\n\nconst ADDRESS_PATTERN = /^0x[a-f0-9]{40}$/iu;\n\nfunction assertValidEvmAddress(value: string, label: string): string {\n const normalized = value.trim();\n if (!ADDRESS_PATTERN.test(normalized)) {\n throw new Error(`${label} must be a valid EVM address`);\n }\n return normalized;\n}\n\nfunction assertPositiveSafeInteger(value: number, label: string): number {\n if (!Number.isSafeInteger(value) || value <= 0) {\n throw new Error(`${label} must be a positive safe integer`);\n }\n return value;\n}\n\nfunction assertTokenDecimals(value: number, label: string): number {\n if (!Number.isInteger(value) || value < 0 || value > 255) {\n throw new Error(`${label} must be an integer between 0 and 255`);\n }\n return value;\n}\n\nfunction assertOptionalTokenAmount(value: number | null | undefined, label: string): number | undefined {\n if (value == null) {\n return undefined;\n }\n if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {\n throw new Error(`${label} must be a positive finite number`);\n }\n return value;\n}\n\nfunction assertOptionalTrimmedString(value: string | null | undefined, label: string): string | undefined {\n if (value == null) {\n return undefined;\n }\n const normalized = value.trim();\n if (!normalized) {\n return undefined;\n }\n return normalized;\n}\n\nfunction assertRequiredTrimmedString(value: string | null | undefined, label: string): string {\n const normalized = assertOptionalTrimmedString(value, label);\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n return normalized;\n}\n\nfunction assertOptionalStringArray(value: string[] | null | undefined, label: string): string[] | undefined {\n if (value == null) {\n return undefined;\n }\n if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {\n throw new Error(`${label} must be an array of strings`);\n }\n const normalized = value\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction normalizeWalletProfile(profile: WalletProfile | null | undefined): WalletProfile | undefined {\n if (profile == null) {\n return undefined;\n }\n\n return {\n vaultKeyId: assertOptionalTrimmedString(profile.vaultKeyId, 'wallet.vaultKeyId'),\n vaultPublicKey: assertRequiredTrimmedString(profile.vaultPublicKey, 'wallet.vaultPublicKey'),\n address: profile.address\n ? assertValidEvmAddress(profile.address, 'wallet.address')\n : undefined,\n agentKeyId: assertOptionalTrimmedString(profile.agentKeyId, 'wallet.agentKeyId'),\n policyAttachment: assertRequiredTrimmedString(profile.policyAttachment, 'wallet.policyAttachment'),\n attachedPolicyIds: assertOptionalStringArray(profile.attachedPolicyIds, 'wallet.attachedPolicyIds'),\n policyNote: assertOptionalTrimmedString(profile.policyNote, 'wallet.policyNote'),\n networkScope: assertOptionalTrimmedString(profile.networkScope, 'wallet.networkScope'),\n assetScope: assertOptionalTrimmedString(profile.assetScope, 'wallet.assetScope'),\n recipientScope: assertOptionalTrimmedString(profile.recipientScope, 'wallet.recipientScope'),\n };\n}\n\nfunction normalizeTokenPolicyProfile(tokenKey: string, chainKey: string, policy: TokenPolicyProfile | undefined) {\n if (!policy) {\n return undefined;\n }\n return {\n perTxAmount: assertOptionalTokenAmount(policy.perTxAmount, `token '${tokenKey}' chain '${chainKey}' perTxAmount`),\n dailyAmount: assertOptionalTokenAmount(policy.dailyAmount, `token '${tokenKey}' chain '${chainKey}' dailyAmount`),\n weeklyAmount: assertOptionalTokenAmount(policy.weeklyAmount, `token '${tokenKey}' chain '${chainKey}' weeklyAmount`),\n perTxAmountDecimal: assertOptionalTrimmedString(policy.perTxAmountDecimal, `token '${tokenKey}' chain '${chainKey}' perTxAmountDecimal`),\n dailyAmountDecimal: assertOptionalTrimmedString(policy.dailyAmountDecimal, `token '${tokenKey}' chain '${chainKey}' dailyAmountDecimal`),\n weeklyAmountDecimal: assertOptionalTrimmedString(policy.weeklyAmountDecimal, `token '${tokenKey}' chain '${chainKey}' weeklyAmountDecimal`),\n perTxLimit: assertOptionalTrimmedString(policy.perTxLimit, `token '${tokenKey}' chain '${chainKey}' perTxLimit`),\n dailyLimit: assertOptionalTrimmedString(policy.dailyLimit, `token '${tokenKey}' chain '${chainKey}' dailyLimit`),\n weeklyLimit: assertOptionalTrimmedString(policy.weeklyLimit, `token '${tokenKey}' chain '${chainKey}' weeklyLimit`),\n maxGasPerChainWei: assertOptionalTrimmedString(policy.maxGasPerChainWei, `token '${tokenKey}' chain '${chainKey}' maxGasPerChainWei`),\n dailyMaxTxCount: assertOptionalTrimmedString(policy.dailyMaxTxCount, `token '${tokenKey}' chain '${chainKey}' dailyMaxTxCount`),\n perTxMaxFeePerGasGwei: assertOptionalTrimmedString(policy.perTxMaxFeePerGasGwei, `token '${tokenKey}' chain '${chainKey}' perTxMaxFeePerGasGwei`),\n perTxMaxFeePerGasWei: assertOptionalTrimmedString(policy.perTxMaxFeePerGasWei, `token '${tokenKey}' chain '${chainKey}' perTxMaxFeePerGasWei`),\n perTxMaxPriorityFeePerGasWei: assertOptionalTrimmedString(policy.perTxMaxPriorityFeePerGasWei, `token '${tokenKey}' chain '${chainKey}' perTxMaxPriorityFeePerGasWei`),\n perTxMaxCalldataBytes: assertOptionalTrimmedString(policy.perTxMaxCalldataBytes, `token '${tokenKey}' chain '${chainKey}' perTxMaxCalldataBytes`),\n } satisfies TokenPolicyProfile;\n}\n\nfunction normalizeTokenDestinationOverrideProfile(\n tokenKey: string,\n profile: TokenDestinationOverrideProfile\n): TokenDestinationOverrideProfile {\n const recipient = assertValidEvmAddress(profile.recipient, `token '${tokenKey}' destination override recipient`);\n return {\n recipient,\n limits: normalizeTokenPolicyProfile(tokenKey, 'override', profile.limits) ?? {},\n };\n}\n\nfunction normalizeTokenManualApprovalProfile(\n tokenKey: string,\n profile: TokenManualApprovalProfile\n): TokenManualApprovalProfile {\n return {\n priority: profile.priority === undefined ? undefined : assertPositiveSafeInteger(profile.priority, `token '${tokenKey}' manual approval priority`),\n recipient: profile.recipient\n ? assertValidEvmAddress(profile.recipient, `token '${tokenKey}' manual approval recipient`)\n : undefined,\n minAmount: assertOptionalTokenAmount(profile.minAmount, `token '${tokenKey}' manual approval minAmount`),\n maxAmount: assertOptionalTokenAmount(profile.maxAmount, `token '${tokenKey}' manual approval maxAmount`),\n minAmountDecimal: assertOptionalTrimmedString(profile.minAmountDecimal, `token '${tokenKey}' manual approval minAmountDecimal`),\n maxAmountDecimal: assertOptionalTrimmedString(profile.maxAmountDecimal, `token '${tokenKey}' manual approval maxAmountDecimal`),\n minAmountWei: assertOptionalTrimmedString(profile.minAmountWei, `token '${tokenKey}' manual approval minAmountWei`),\n maxAmountWei: assertOptionalTrimmedString(profile.maxAmountWei, `token '${tokenKey}' manual approval maxAmountWei`),\n };\n}\n\nfunction normalizeTokenChainProfile(tokenKey: string, chainKey: string, profile: TokenChainProfile): TokenChainProfile {\n const normalizedChainKey = chainKey.trim().toLowerCase();\n if (!normalizedChainKey) {\n throw new Error(`token '${tokenKey}' chain key is required`);\n }\n\n const normalized: TokenChainProfile = {\n chainId: assertPositiveSafeInteger(profile.chainId, `token '${tokenKey}' chain '${normalizedChainKey}' chainId`),\n isNative: Boolean(profile.isNative),\n decimals: assertTokenDecimals(profile.decimals, `token '${tokenKey}' chain '${normalizedChainKey}' decimals`),\n defaultPolicy: normalizeTokenPolicyProfile(tokenKey, normalizedChainKey, profile.defaultPolicy),\n };\n\n if (normalized.isNative) {\n if (profile.address?.trim()) {\n throw new Error(`token '${tokenKey}' chain '${normalizedChainKey}' must not set address when isNative=true`);\n }\n } else {\n normalized.address = assertValidEvmAddress(\n profile.address ?? '',\n `token '${tokenKey}' chain '${normalizedChainKey}' address`\n );\n }\n\n return normalized;\n}\n\nfunction normalizeTokenProfile(key: string, profile: TokenProfile): TokenProfile {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('token profile key is required');\n }\n\n const symbol = profile.symbol?.trim();\n if (!symbol) {\n throw new Error(`token profile '${normalizedKey}' symbol is required`);\n }\n const name = assertOptionalTrimmedString(profile.name, `token profile '${normalizedKey}' name`);\n\n const normalizedChains: Record<string, TokenChainProfile> = {};\n for (const [chainKey, chainProfile] of Object.entries(profile.chains ?? {})) {\n const normalizedChainKey = chainKey.trim().toLowerCase();\n if (!normalizedChainKey) {\n throw new Error(`token profile '${normalizedKey}' contains an empty chain key`);\n }\n normalizedChains[normalizedChainKey] = normalizeTokenChainProfile(normalizedKey, normalizedChainKey, chainProfile);\n }\n\n return {\n name,\n symbol,\n defaultPolicy: normalizeTokenPolicyProfile(normalizedKey, 'default', profile.defaultPolicy),\n destinationOverrides: (profile.destinationOverrides ?? []).map((item) =>\n normalizeTokenDestinationOverrideProfile(normalizedKey, item)\n ),\n manualApprovalPolicies: (profile.manualApprovalPolicies ?? []).map((item) =>\n normalizeTokenManualApprovalProfile(normalizedKey, item)\n ),\n chains: normalizedChains,\n };\n}\n\nfunction normalizeChainProfileEntry(key: string, profile: ChainProfile): ChainProfile {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n\n const name = profile.name?.trim() || normalizedKey;\n return {\n chainId: assertPositiveSafeInteger(profile.chainId, `chain profile '${normalizedKey}' chainId`),\n name,\n rpcUrl: profile.rpcUrl\n ? assertSafeRpcUrl(profile.rpcUrl, `chain profile '${normalizedKey}' rpcUrl`)\n : undefined,\n };\n}\n\nfunction normalizeChainProfiles(profiles: Record<string, ChainProfile> | undefined): Record<string, ChainProfile> {\n const normalized: Record<string, ChainProfile> = {};\n for (const [key, profile] of Object.entries(profiles ?? {})) {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n normalized[normalizedKey] = normalizeChainProfileEntry(normalizedKey, profile);\n }\n return normalized;\n}\n\nfunction normalizeTokenProfiles(profiles: Record<string, TokenProfile> | undefined): Record<string, TokenProfile> {\n const normalized: Record<string, TokenProfile> = {};\n for (const [key, profile] of Object.entries(profiles ?? {})) {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('token profile key is required');\n }\n normalized[normalizedKey] = normalizeTokenProfile(normalizedKey, profile);\n }\n return normalized;\n}\n\nfunction normalizePath(targetPath: string): string {\n return path.resolve(targetPath);\n}\n\nfunction requirePathValue(targetPath: string, label: string): string {\n const normalized = targetPath.trim();\n if (!normalized) {\n throw new Error(`${label} is required`);\n }\n\n return normalizePath(normalized);\n}\n\nfunction readLstat(targetPath: string): fs.Stats | null {\n try {\n return fs.lstatSync(targetPath);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n}\n\nfunction readLstatAllowInaccessible(targetPath: string): fs.Stats | 'inaccessible' | null {\n try {\n return fs.lstatSync(targetPath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n return null;\n }\n if (code === 'EACCES' || code === 'EPERM') {\n return 'inaccessible';\n }\n throw error;\n }\n}\n\nfunction isStableRootOwnedSymlink(stats: fs.Stats, targetPath: string): boolean {\n if (process.platform === 'win32' || typeof stats.uid !== 'number' || stats.uid !== 0) {\n return false;\n }\n\n const parentPath = path.dirname(targetPath);\n const parentStats = readLstat(parentPath);\n return Boolean(\n parentStats\n && parentStats.isDirectory()\n && typeof parentStats.uid === 'number'\n && parentStats.uid === 0\n && (parentStats.mode & GROUP_OTHER_WRITE_MODE_MASK) === 0\n );\n}\n\nfunction assertNoSymlinkAncestorDirectories(targetPath: string, label: string): void {\n const normalized = normalizePath(targetPath);\n const parent = path.dirname(normalized);\n if (parent === normalized) {\n return;\n }\n\n const { root } = path.parse(parent);\n const relativeParent = parent.slice(root.length);\n if (!relativeParent) {\n return;\n }\n\n let currentPath = root;\n for (const segment of relativeParent.split(path.sep).filter(Boolean)) {\n currentPath = path.join(currentPath, segment);\n const stats = readLstat(currentPath);\n if (!stats) {\n break;\n }\n if (stats.isSymbolicLink()) {\n if (isStableRootOwnedSymlink(stats, currentPath)) {\n continue;\n }\n throw new Error(`${label} '${normalized}' must not traverse symlinked ancestor directories`);\n }\n }\n}\n\nfunction findNearestExistingPath(targetPath: string): { path: string; stats: fs.Stats } {\n let currentPath = normalizePath(targetPath);\n\n while (true) {\n const stats = readLstat(currentPath);\n if (stats) {\n return {\n path: currentPath,\n stats\n };\n }\n\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n throw new Error(`No existing ancestor directory found for '${targetPath}'`);\n }\n\n currentPath = parentPath;\n }\n}\n\nexport function allowedOwnerUids(): Set<number> {\n const allowed = new Set<number>();\n const effectiveUid = typeof process.geteuid === 'function' ? process.geteuid() : null;\n if (effectiveUid !== null) {\n allowed.add(effectiveUid);\n }\n\n const sudoUid = process.env.SUDO_UID?.trim();\n if (effectiveUid === 0 && sudoUid && /^\\d+$/u.test(sudoUid)) {\n allowed.add(Number(sudoUid));\n }\n\n return allowed;\n}\n\nfunction assertTrustedOwner(stats: fs.Stats, targetPath: string, label: string): void {\n if (process.platform === 'win32' || typeof stats.uid !== 'number') {\n return;\n }\n\n if (stats.uid === 0) {\n return;\n }\n\n const allowed = allowedOwnerUids();\n if (!allowed.has(stats.uid)) {\n throw new Error(\n `${label} '${targetPath}' must be owned by the current user, sudo caller, or root`\n );\n }\n}\n\nfunction assertSecureDirectory(stats: fs.Stats, targetPath: string, label: string): void {\n assertTrustedOwner(stats, targetPath, label);\n if (process.platform === 'win32') {\n return;\n }\n\n if ((stats.mode & GROUP_OTHER_WRITE_MODE_MASK) !== 0) {\n throw new Error(`${label} '${targetPath}' must not be writable by group/other`);\n }\n}\n\nfunction isStickyDirectory(stats: fs.Stats): boolean {\n return process.platform !== 'win32' && (stats.mode & STICKY_BIT_MODE) !== 0;\n}\n\nfunction assertSecureDirectoryPath(targetPath: string, label: string): void {\n const normalized = normalizePath(targetPath);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const targetStats = fs.lstatSync(normalized);\n if (targetStats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!targetStats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n\n assertSecureDirectory(targetStats, normalized, label);\n\n const ancestors: string[] = [];\n let currentPath = fs.realpathSync.native(normalized);\n\n while (true) {\n ancestors.push(currentPath);\n const parentPath = path.dirname(currentPath);\n if (parentPath === currentPath) {\n break;\n }\n currentPath = parentPath;\n }\n\n for (const [index, currentDirectory] of ancestors.entries()) {\n if (index === 0) {\n continue;\n }\n\n const stats = fs.lstatSync(currentDirectory);\n if (!stats.isDirectory()) {\n throw new Error(`${label} '${currentDirectory}' must be a directory`);\n }\n\n assertTrustedOwner(stats, currentDirectory, label);\n if (process.platform !== 'win32' && (stats.mode & GROUP_OTHER_WRITE_MODE_MASK) !== 0) {\n const allowStickyAncestor = index > 0 && isStickyDirectory(stats);\n if (!allowStickyAncestor) {\n throw new Error(`${label} '${currentDirectory}' must not be writable by group/other`);\n }\n }\n }\n}\n\nfunction assertSecureFile(stats: fs.Stats, targetPath: string, label: string): void {\n assertTrustedOwner(stats, targetPath, label);\n if (process.platform === 'win32') {\n return;\n }\n\n if ((stats.mode & PRIVATE_FILE_MODE_MASK) !== 0) {\n throw new Error(`${label} '${targetPath}' must not grant group/other permissions`);\n }\n}\n\nfunction assertNotSymlink(targetPath: string, label: string): fs.Stats | null {\n const stats = readLstat(targetPath);\n if (stats?.isSymbolicLink()) {\n throw new Error(`${label} '${targetPath}' must not be a symlink`);\n }\n return stats;\n}\n\nfunction tightenPermissions(targetPath: string, mode: number) {\n try {\n fs.chmodSync(targetPath, mode);\n } catch {}\n}\n\nfunction ensurePrivateDirectory(targetPath: string, label: string): string {\n const normalized = normalizePath(targetPath);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const stats = assertNotSymlink(normalized, label);\n if (stats && !stats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n if (!stats) {\n fs.mkdirSync(normalized, { recursive: true, mode: PRIVATE_DIR_MODE });\n }\n tightenPermissions(normalized, PRIVATE_DIR_MODE);\n assertSecureDirectoryPath(normalized, label);\n return normalized;\n}\n\nfunction readUtf8FileSecure(targetPath: string, label: string, maxBytes?: number): string {\n const normalized = normalizePath(targetPath);\n assertSecureDirectoryPath(path.dirname(normalized), `${label} parent directory`);\n const openFlags = process.platform === 'win32'\n ? fs.constants.O_RDONLY\n : fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW;\n const fd = fs.openSync(normalized, openFlags);\n\n try {\n const stats = fs.fstatSync(fd);\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n assertSecureFile(stats, normalized, label);\n if (maxBytes !== undefined && stats.size > maxBytes) {\n throw new Error(`${label} '${normalized}' must not exceed ${maxBytes} bytes`);\n }\n return fs.readFileSync(fd, 'utf8');\n } finally {\n fs.closeSync(fd);\n }\n}\n\nfunction readPrivateJsonFile<T>(targetPath: string, label: string): T | null {\n const normalized = normalizePath(targetPath);\n const stats = assertNotSymlink(normalized, label);\n if (!stats) {\n return null;\n }\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n tightenPermissions(normalized, PRIVATE_FILE_MODE);\n return JSON.parse(readUtf8FileSecure(normalized, label, MAX_CONFIG_FILE_BYTES)) as T;\n}\n\nfunction assertSecurePlannedDirectoryPath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertNoSymlinkAncestorDirectories(normalized, label);\n const stats = readLstat(normalized);\n\n if (stats) {\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!stats.isDirectory()) {\n throw new Error(`${label} '${normalized}' must be a directory`);\n }\n\n assertSecureDirectoryPath(normalized, label);\n return normalized;\n }\n\n const nearestExistingPath = findNearestExistingPath(normalized);\n if (nearestExistingPath.stats.isSymbolicLink()) {\n throw new Error(`${label} '${nearestExistingPath.path}' must not be a symlink`);\n }\n if (!nearestExistingPath.stats.isDirectory()) {\n throw new Error(`${label} '${nearestExistingPath.path}' must be a directory`);\n }\n\n assertSecureDirectoryPath(nearestExistingPath.path, label);\n return normalized;\n}\n\nfunction assertSecurePlannedDaemonSocketPath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertSecurePlannedDirectoryPath(path.dirname(normalized), `${label} directory`);\n\n const stats = readLstat(normalized);\n if (!stats) {\n return normalized;\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (process.platform !== 'win32' && !stats.isSocket()) {\n throw new Error(`${label} '${normalized}' must be a unix socket`);\n }\n\n assertTrustedOwner(stats, normalized, label);\n return normalized;\n}\n\nfunction assertSecurePlannedPrivateFilePath(targetPath: string, label: string): string {\n const normalized = requirePathValue(targetPath, label);\n assertSecurePlannedDirectoryPath(path.dirname(normalized), `${label} directory`);\n\n const stats = readLstatAllowInaccessible(normalized);\n if (!stats || stats === 'inaccessible') {\n return normalized;\n }\n\n if (stats.isSymbolicLink()) {\n throw new Error(`${label} '${normalized}' must not be a symlink`);\n }\n if (!stats.isFile()) {\n throw new Error(`${label} '${normalized}' must be a regular file`);\n }\n\n assertSecureFile(stats, normalized, label);\n return normalized;\n}\n\nfunction writePrivateFile(targetPath: string, contents: string, label: string) {\n const normalized = normalizePath(targetPath);\n const parent = ensurePrivateDirectory(path.dirname(normalized), `${label} parent`);\n assertNotSymlink(normalized, label);\n\n const tempPath = path.join(\n parent,\n `.${path.basename(normalized)}.tmp-${process.pid}-${Date.now()}`\n );\n\n try {\n fs.writeFileSync(tempPath, contents, {\n encoding: 'utf8',\n mode: PRIVATE_FILE_MODE,\n flag: 'wx'\n });\n tightenPermissions(tempPath, PRIVATE_FILE_MODE);\n fs.renameSync(tempPath, normalized);\n tightenPermissions(normalized, PRIVATE_FILE_MODE);\n } finally {\n try {\n if (fs.existsSync(tempPath)) {\n fs.rmSync(tempPath);\n }\n } catch {}\n }\n}\n\nfunction normalizedDefaultConfig(): WlfiConfig {\n return {\n daemonSocket: defaultDaemonSocketPath(),\n stateFile: defaultStateFilePath(),\n rustBinDir: defaultRustBinDir(),\n chains: defaultChainProfiles(),\n tokens: defaultTokenProfiles()\n };\n}\n\nfunction applySeedDefaultsIfLegacyEmpty(config: WlfiConfig): WlfiConfig {\n const chainCount = Object.keys(config.chains ?? {}).length;\n const tokenCount = Object.keys(config.tokens ?? {}).length;\n if (chainCount === 0 && tokenCount === 0) {\n return {\n ...config,\n chains: defaultChainProfiles(),\n tokens: defaultTokenProfiles(),\n };\n }\n return config;\n}\n\nexport function resolveWlfiHome(): string {\n const explicit = process.env.WLFI_HOME?.trim();\n if (explicit) {\n return normalizePath(explicit);\n }\n return path.join(os.homedir(), WLFI_DIRNAME);\n}\n\nexport function resolveConfigPath(): string {\n return path.join(resolveWlfiHome(), CONFIG_FILENAME);\n}\n\nexport function defaultDaemonSocketPath(): string {\n return path.join(resolveWlfiHome(), 'daemon.sock');\n}\n\nexport function defaultStateFilePath(): string {\n return path.join(resolveWlfiHome(), 'daemon-state.enc');\n}\n\nexport function defaultRustBinDir(): string {\n return path.join(resolveWlfiHome(), 'bin');\n}\n\nexport function defaultConfig(): WlfiConfig {\n return normalizedDefaultConfig();\n}\n\nexport function ensureWlfiHome(): string {\n return ensurePrivateDirectory(resolveWlfiHome(), 'WLFI home');\n}\n\nexport function readConfig(): WlfiConfig {\n ensureWlfiHome();\n const parsed = readPrivateJsonFile<WlfiConfig>(resolveConfigPath(), 'config file');\n const merged = applySeedDefaultsIfLegacyEmpty({\n ...normalizedDefaultConfig(),\n ...(parsed ?? {})\n } satisfies WlfiConfig);\n\n return {\n ...merged,\n wallet: normalizeWalletProfile(merged.wallet),\n chains: normalizeChainProfiles(merged.chains),\n tokens: normalizeTokenProfiles(merged.tokens),\n };\n}\n\nexport function writeConfig(nextConfig: WlfiConfig): WlfiConfig {\n ensureWlfiHome();\n const merged: WlfiConfig = {\n ...normalizedDefaultConfig(),\n ...readConfig(),\n ...nextConfig\n };\n\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'rpcUrl') && merged.rpcUrl !== undefined) {\n merged.rpcUrl = assertSafeRpcUrl(merged.rpcUrl, 'rpcUrl');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'daemonSocket') && merged.daemonSocket !== undefined) {\n merged.daemonSocket = assertSecurePlannedDaemonSocketPath(merged.daemonSocket, 'daemonSocket');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'stateFile') && merged.stateFile !== undefined) {\n merged.stateFile = assertSecurePlannedPrivateFilePath(merged.stateFile, 'stateFile');\n }\n if (Object.prototype.hasOwnProperty.call(nextConfig, 'rustBinDir') && merged.rustBinDir !== undefined) {\n merged.rustBinDir = assertSecurePlannedDirectoryPath(merged.rustBinDir, 'rustBinDir');\n }\n\n merged.wallet = normalizeWalletProfile(merged.wallet);\n merged.chains = normalizeChainProfiles(merged.chains);\n merged.tokens = normalizeTokenProfiles(merged.tokens);\n\n writePrivateFile(resolveConfigPath(), JSON.stringify(merged, null, 2) + '\\n', 'config file');\n return merged;\n}\n\nexport function deleteConfigKey(key: keyof WlfiConfig): WlfiConfig {\n ensureWlfiHome();\n const current = {\n ...normalizedDefaultConfig(),\n ...readConfig()\n };\n delete current[key];\n\n const normalized = {\n ...normalizedDefaultConfig(),\n ...current,\n chains: current.chains ?? {},\n tokens: current.tokens ?? {}\n };\n\n writePrivateFile(resolveConfigPath(), JSON.stringify(normalized, null, 2) + '\\n', 'config file');\n return normalized;\n}\n\nexport function listBuiltinChains(): ChainProfile[] {\n return Object.entries(BUILTIN_CHAINS)\n .map(([key, value]) => ({ ...value, name: key }))\n .sort((left, right) => left.chainId - right.chainId || left.name.localeCompare(right.name));\n}\n\nexport function listBuiltinTokens(): TokenProfileEntry[] {\n return Object.entries(BUILTIN_TOKENS)\n .map(([key, value]) => ({\n key,\n name: value.name,\n symbol: value.symbol,\n chains: Object.entries(value.chains ?? {})\n .map(([chainKey, chainValue]) => ({ key: chainKey, ...chainValue }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key)),\n }))\n .sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport function listConfiguredTokens(\n config: WlfiConfig = readConfig()\n): TokenProfileEntry[] {\n return Object.entries(config.tokens ?? {})\n .map(([key, value]) => ({\n key,\n name: value.name,\n symbol: value.symbol,\n chains: Object.entries(value.chains ?? {})\n .map(([chainKey, chainValue]) => ({ key: chainKey, ...chainValue }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key)),\n }))\n .sort((left, right) => left.key.localeCompare(right.key));\n}\n\nexport function resolveTokenProfile(\n selector: string,\n config: WlfiConfig = readConfig()\n): (TokenProfile & { key: string; source: 'configured' | 'builtin' }) | null {\n const normalized = selector.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n for (const [key, value] of Object.entries(config.tokens ?? {})) {\n if (key.toLowerCase() === normalized || value.symbol.toLowerCase() === normalized) {\n return { key, source: 'configured', ...value };\n }\n }\n\n for (const [key, value] of Object.entries(BUILTIN_TOKENS)) {\n if (key.toLowerCase() === normalized || value.symbol.toLowerCase() === normalized) {\n return { key, source: 'builtin', ...value };\n }\n }\n\n return null;\n}\n\nexport function listConfiguredChains(config: WlfiConfig = readConfig()): Array<ChainProfile & { key: string }> {\n return Object.entries(config.chains ?? {})\n .map(([key, value]) => ({ key, ...value }))\n .sort((left, right) => left.chainId - right.chainId || left.key.localeCompare(right.key));\n}\n\nexport function resolveChainProfile(selector: string, config: WlfiConfig = readConfig()): (ChainProfile & { key?: string; source: 'configured' | 'builtin' | 'active' }) | null {\n const normalized = selector.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n for (const [key, value] of Object.entries(config.chains ?? {})) {\n if (key.toLowerCase() === normalized || value.name.toLowerCase() === normalized || String(value.chainId) === selector) {\n return { ...value, key, source: 'configured' };\n }\n }\n\n if (BUILTIN_CHAINS[normalized]) {\n return { ...BUILTIN_CHAINS[normalized], key: normalized, source: 'builtin' };\n }\n\n if (config.chainId !== undefined && String(config.chainId) === selector) {\n return {\n chainId: config.chainId,\n name: config.chainName ?? normalized,\n rpcUrl: config.rpcUrl,\n source: 'active'\n };\n }\n\n return null;\n}\n\nexport function saveChainProfile(key: string, profile: ChainProfile): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n if (!normalizedKey) {\n throw new Error('chain profile key is required');\n }\n\n const normalizedProfile = normalizeChainProfileEntry(normalizedKey, profile);\n\n return writeConfig({\n chains: {\n ...(readConfig().chains ?? {}),\n [normalizedKey]: normalizedProfile\n }\n });\n}\n\nexport function removeChainProfile(key: string): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n const nextChains = { ...(readConfig().chains ?? {}) };\n delete nextChains[normalizedKey];\n return writeConfig({ chains: nextChains });\n}\n\nexport function saveTokenProfile(key: string, profile: TokenProfile): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n return writeConfig({\n tokens: {\n ...(readConfig().tokens ?? {}),\n [normalizedKey]: normalizeTokenProfile(normalizedKey, profile),\n },\n });\n}\n\nexport function saveTokenChainProfile(\n tokenKey: string,\n chainKey: string,\n profile: TokenChainProfile,\n options: { symbol?: string } = {}\n): WlfiConfig {\n const normalizedTokenKey = tokenKey.trim().toLowerCase();\n const normalizedChainKey = chainKey.trim().toLowerCase();\n const current = readConfig();\n const existing = current.tokens?.[normalizedTokenKey];\n const symbol = options.symbol?.trim() || existing?.symbol;\n if (!symbol) {\n throw new Error(`token '${normalizedTokenKey}' symbol is required`);\n }\n\n return writeConfig({\n tokens: {\n ...(current.tokens ?? {}),\n [normalizedTokenKey]: normalizeTokenProfile(normalizedTokenKey, {\n name: existing?.name,\n symbol,\n defaultPolicy: existing?.defaultPolicy,\n destinationOverrides: existing?.destinationOverrides,\n manualApprovalPolicies: existing?.manualApprovalPolicies,\n chains: {\n ...(existing?.chains ?? {}),\n [normalizedChainKey]: normalizeTokenChainProfile(normalizedTokenKey, normalizedChainKey, profile),\n },\n }),\n },\n });\n}\n\nexport function removeTokenProfile(key: string): WlfiConfig {\n const normalizedKey = key.trim().toLowerCase();\n const nextTokens = { ...(readConfig().tokens ?? {}) };\n delete nextTokens[normalizedKey];\n return writeConfig({ tokens: nextTokens });\n}\n\nexport function removeTokenChainProfile(tokenKey: string, chainKey: string): WlfiConfig {\n const normalizedTokenKey = tokenKey.trim().toLowerCase();\n const normalizedChainKey = chainKey.trim().toLowerCase();\n const current = readConfig();\n const token = current.tokens?.[normalizedTokenKey];\n if (!token) {\n return current;\n }\n\n const nextChains = { ...(token.chains ?? {}) };\n delete nextChains[normalizedChainKey];\n const nextTokens = { ...(current.tokens ?? {}) };\n if (Object.keys(nextChains).length === 0) {\n delete nextTokens[normalizedTokenKey];\n } else {\n nextTokens[normalizedTokenKey] = normalizeTokenProfile(normalizedTokenKey, {\n name: token.name,\n symbol: token.symbol,\n defaultPolicy: token.defaultPolicy,\n destinationOverrides: token.destinationOverrides,\n manualApprovalPolicies: token.manualApprovalPolicies,\n chains: nextChains,\n });\n }\n return writeConfig({ tokens: nextTokens });\n}\n\nexport function switchActiveChain(selector: string, options: { rpcUrl?: string; persistProfile?: boolean } = {}): WlfiConfig {\n const config = readConfig();\n const profile = resolveChainProfile(selector, config);\n if (!profile) {\n throw new Error(`Unknown chain selector: ${selector}`);\n }\n\n const nextRpcUrl = options.rpcUrl ?? profile.rpcUrl;\n const normalizedRpcUrl = nextRpcUrl ? assertSafeRpcUrl(nextRpcUrl, 'rpcUrl') : undefined;\n let next = writeConfig({\n chainId: profile.chainId,\n chainName: profile.name,\n rpcUrl: normalizedRpcUrl,\n chains: config.chains ?? {}\n });\n\n if (options.persistProfile) {\n next = saveChainProfile(profile.key ?? profile.name, {\n chainId: profile.chainId,\n name: profile.name,\n rpcUrl: normalizedRpcUrl\n });\n }\n\n return next;\n}\n\nexport function redactConfig(config: WlfiConfig): Record<string, unknown> {\n return {\n ...config,\n agentAuthToken: config.agentAuthToken ? '<redacted>' : undefined,\n paths: {\n wlfiHome: resolveWlfiHome(),\n configPath: resolveConfigPath(),\n daemonSocket: config.daemonSocket ?? defaultDaemonSocketPath(),\n stateFile: config.stateFile ?? defaultStateFilePath(),\n rustBinDir: config.rustBinDir ?? defaultRustBinDir()\n }\n };\n}\n\nexport function resolveRustBinaryPath(binaryName: string, config: WlfiConfig = readConfig()): string {\n return path.join(config.rustBinDir ?? defaultRustBinDir(), binaryName + (process.platform === 'win32' ? '.exe' : ''));\n}\n"],"mappings":"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","names":[]}
@@ -148,23 +148,6 @@ export const BUILTIN_TOKENS: Record<string, TokenProfile> = {
148
148
  arbitrum: { chainId: 42161, isNative: true, decimals: 18 },
149
149
  },
150
150
  },
151
- usdc: {
152
- symbol: 'USDC',
153
- chains: {
154
- ethereum: {
155
- chainId: 1,
156
- isNative: false,
157
- address: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
158
- decimals: 6,
159
- },
160
- base: {
161
- chainId: 8453,
162
- isNative: false,
163
- address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
164
- decimals: 6,
165
- },
166
- },
167
- },
168
151
  usd1: {
169
152
  name: 'USD1',
170
153
  symbol: 'USD1',
@@ -10,23 +10,23 @@
10
10
  CLI Target: node20
11
11
  CLI Cleaning output folder
12
12
  ESM Build start
13
- DTS Build start
14
- ESM dist/secp256k1-WCNM675D.cjs 331.00 B
15
13
  ESM dist/ccip-OWJLAW55.cjs 344.00 B
16
14
  ESM dist/chunk-CDO2GWRD.cjs 11.91 KB
17
- ESM dist/chunk-QGTNTFJ7.cjs 69.15 KB
18
- ESM dist/index.cjs 248.00 KB
15
+ ESM dist/secp256k1-WCNM675D.cjs 331.00 B
16
+ ESM dist/chunk-APQIFZ3B.cjs 212.06 KB
19
17
  ESM dist/_esm-BCLXDO2R.cjs 122.75 KB
18
+ ESM dist/index.cjs 247.64 KB
19
+ ESM dist/chunk-QGTNTFJ7.cjs 69.15 KB
20
20
  ESM dist/chunk-TZDTAHWR.cjs 1.89 KB
21
- ESM dist/chunk-APQIFZ3B.cjs 212.06 KB
21
+ ESM dist/chunk-CDO2GWRD.cjs.map 42.64 KB
22
22
  ESM dist/ccip-OWJLAW55.cjs.map 71.00 B
23
23
  ESM dist/secp256k1-WCNM675D.cjs.map 71.00 B
24
- ESM dist/chunk-CDO2GWRD.cjs.map 42.64 KB
25
- ESM dist/chunk-QGTNTFJ7.cjs.map 194.07 KB
24
+ ESM dist/_esm-BCLXDO2R.cjs.map 196.57 KB
26
25
  ESM dist/chunk-TZDTAHWR.cjs.map 71.00 B
27
- ESM dist/index.cjs.map 1011.42 KB
26
+ ESM dist/chunk-QGTNTFJ7.cjs.map 194.07 KB
28
27
  ESM dist/chunk-APQIFZ3B.cjs.map 544.22 KB
29
- ESM dist/_esm-BCLXDO2R.cjs.map 196.57 KB
30
- ESM ⚡️ Build success in 190ms
31
- DTS ⚡️ Build success in 1656ms
28
+ ESM dist/index.cjs.map 1010.81 KB
29
+ ESM ⚡️ Build success in 135ms
30
+ DTS Build start
31
+ DTS ⚡️ Build success in 1411ms
32
32
  DTS dist/index.d.ts 201.02 KB
@@ -188,23 +188,6 @@ var BUILTIN_TOKENS = {
188
188
  arbitrum: { chainId: 42161, isNative: true, decimals: 18 }
189
189
  }
190
190
  },
191
- usdc: {
192
- symbol: "USDC",
193
- chains: {
194
- ethereum: {
195
- chainId: 1,
196
- isNative: false,
197
- address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
198
- decimals: 6
199
- },
200
- base: {
201
- chainId: 8453,
202
- isNative: false,
203
- address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
204
- decimals: 6
205
- }
206
- }
207
- },
208
191
  usd1: {
209
192
  name: "USD1",
210
193
  symbol: "USD1",