UNPKG

accounts

Version:

Tempo Accounts SDK

142 lines 5.8 kB
import {} from 'ox'; import { createClient, http, } from 'viem'; import { Transaction } from 'viem/tempo'; const defaultClients = new Map(); const clients = new WeakMap(); /** Resolves a viem Client for a given chain ID (cached). */ export function fromChainId(chainId, options) { const { chains, feePayer: feePayerOption, provider, store, transports } = options; const feePayerUrl = (() => { if (feePayerOption === false) return undefined; if (typeof feePayerOption === 'string') return normalizeFeePayerUrl(feePayerOption); if (feePayerOption?.url) return normalizeFeePayerUrl(feePayerOption.url); return undefined; })(); const precedence = (() => { if (typeof feePayerOption === 'object' && feePayerOption !== null) return feePayerOption.precedence ?? 'fee-payer-first'; return 'fee-payer-first'; })(); const id = chainId ?? store.getState().chainId; const key = `${id}:${provider ? 'p' : ''}:${feePayerOption === false ? 'no-fp' : (feePayerUrl ?? '')}:${precedence}`; const scope = provider ?? transports; const cache = (() => { if (!scope) return defaultClients; let map = clients.get(scope); if (!map) { map = new Map(); clients.set(scope, map); } return map; })(); let client = cache.get(key); if (!client) { const chain = chains.find((c) => c.id === id) ?? chains[0]; const base = transports?.[id] ?? http(); const transport_base = provider ? providerTransport(provider, base, chainId === undefined ? undefined : chain.id) : base; const transport = feePayerUrl ? feePayerTransport(transport_base, feePayerUrl, precedence) : transport_base; client = createClient({ chain, transport, pollingInterval: 1000 }); cache.set(key, client); } return client; } /** * Routes account operations through the provider and explicit-chain RPCs * through the requested chain's transport. */ function providerTransport(provider, base, chainId) { return (params) => { const baseTransport = base(params); return { ...baseTransport, async request({ method, params: reqParams }) { if (chainId !== undefined && !usesProvider(method)) return baseTransport.request({ method, params: reqParams }); const params = (() => { if (method !== 'eth_fillTransaction' || chainId === undefined) return reqParams; const request = reqParams?.[0]; if (!request || typeof request !== 'object') return reqParams; return [{ ...request, chainId }]; })(); return provider.request({ method, params, }); }, }; }; } function usesProvider(method) { return (method.startsWith('wallet_') || [ 'eth_accounts', 'eth_fillTransaction', 'eth_requestAccounts', 'eth_sendTransaction', 'eth_sendTransactionSync', 'eth_signTransaction', 'eth_signTypedData_v4', 'personal_sign', ].includes(method)); } /** * Resolves a fee payer URL to an absolute URL string. Relative paths (e.g. * `/relay`) are resolved against `window.location.origin` when running in a * browser; on the server, relative paths are returned as-is. */ function normalizeFeePayerUrl(url) { if (url.startsWith('http://') || url.startsWith('https://')) return url; if (typeof window !== 'undefined') return new URL(url, window.location.origin).href; return url; } function feePayerTransport(base, url, precedence) { return (params) => { const baseTransport = base(params); const sponsor = http(url)(params); return { ...baseTransport, async request({ method, params: rpcParams }) { const args = rpcParams; if (precedence === 'fee-payer-first' && method === 'eth_fillTransaction') { const request = args?.[0]; if (request && typeof request === 'object' && 'feePayer' in request && (request.feePayer === true || typeof request.feePayer === 'string')) return sponsor.request({ method, params: [{ ...request, feePayer: true }], }); } if (method === 'eth_sendRawTransaction' || method === 'eth_sendRawTransactionSync') { const serialized = args?.[0]; if (typeof serialized === 'string' && (serialized.startsWith('0x76') || serialized.startsWith('0x78'))) { const deserialized = Transaction.deserialize(serialized); if ('feePayerSignature' in deserialized && deserialized.feePayerSignature === null) { const signed = await sponsor.request({ method: 'eth_signRawTransaction', params: [serialized], }); return await baseTransport.request({ method, params: [signed] }); } } } return await baseTransport.request({ method, params: rpcParams }); }, }; }; } //# sourceMappingURL=Client.js.map