viem
Version:
113 lines • 4.51 kB
JavaScript
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