UNPKG

viem

Version:

TypeScript Interface for Ethereum

113 lines 4.51 kB
import { parseAccount, } from '../accounts/utils/parseAccount.js'; import { uid } from '../utils/uid.js'; export function createClient(parameters) { const { batch, chain, ccipRead, dataSuffix, key = 'base', name = 'Base Client', tokens, type = 'base', } = parameters; const experimental_blockTag = parameters.experimental_blockTag ?? (typeof chain?.experimental_preconfirmationTime === 'number' ? 'pending' : undefined); const blockTime = chain?.blockTime ?? 12_000; const defaultPollingInterval = Math.min(Math.max(Math.floor(blockTime / 2), 500), 4_000); const pollingInterval = parameters.pollingInterval ?? defaultPollingInterval; const cacheTime = parameters.cacheTime ?? pollingInterval; const account = parameters.account ? parseAccount(parameters.account) : undefined; const { config, request, value } = parameters.transport({ account, chain, pollingInterval, }); const transport = { ...config, ...value }; const client = { account, batch, cacheTime, ccipRead, chain, dataSuffix, key, name, pollingInterval, request, tokens, transport, type, uid: uid(), ...(experimental_blockTag ? { experimental_blockTag } : {}), }; function extend(base) { return (extendFn) => { const extended = extendFn(base); for (const key in client) delete extended[key]; const combined = { ...base, ...extended }; // For keys that exist on both the base client and the extension and // resolve to plain objects (e.g. namespaces like `token`), shallow-merge // their members instead of overwriting. This lets decorators contribute // to the same namespace (e.g. `publicActions` adds read actions and // `walletActions` adds write actions to `client.token`). for (const key in extended) { const a = base[key]; const b = extended[key]; if (isPlainObject(a) && isPlainObject(b)) combined[key] = { ...a, ...b }; } return Object.assign(combined, { extend: extend(combined) }); }; } return Object.assign(client, { extend: extend(client) }); } /** Whether `value` is a plain object (`{}`), as opposed to a function, array, * or class instance. Used to decide which extension namespaces to merge. */ function isPlainObject(value) { if (typeof value !== 'object' || value === null) return false; const prototype = Object.getPrototypeOf(value); return prototype === Object.prototype || prototype === null; } /** * Binds an action function to a `client`, returning a parameter-only version * along with any helpers the action exposes. Helpers that need a client * (`.call`, `.calls`, `.callWithPeriod`, `.estimateGas`, `.prepare`, * `.simulate`) are bound to `client`; pure helpers (`.extractEvent`, * `.extractEvents`) are copied as-is. Used by decorators that attach * namespaced actions to a Client. * @internal */ export function bindActionDecorators(client, action) { const wrapped = (parameters = {}) => action(client, parameters); for (const key of [ 'call', 'calls', 'callWithPeriod', 'estimateGas', 'prepare', 'simulate', ]) if (Object.hasOwn(action, key)) { const helper = action[key]; wrapped[key] = (args = {}) => { // Single-parameter helpers are client-less (e.g. `dex.buy.call(args)`). // Everything else is called with `(client, args)`: two-parameter // helpers, rest-parameter helpers that accept `(client, args)` or // `(args)` (`length === 0`, e.g. `token.transfer.call`), and // zero-argument helpers, which ignore the extra arguments. if (helper.length === 1) return helper(args); return helper(client, args); }; } for (const key of ['extractEvent', 'extractEvents']) if (Object.hasOwn(action, key)) wrapped[key] = action[key]; return wrapped; } /** * Defines a typed JSON-RPC schema for the client. * Note: This is a runtime noop function. */ export function rpcSchema() { return null; } //# sourceMappingURL=createClient.js.map