@wagmi/core
Version:
VanillaJS library for Ethereum
757 lines • 24 kB
JavaScript
import { sendTransaction as viem_sendTransaction, sendTransactionSync as viem_sendTransactionSync, } from 'viem/actions';
import { Actions } from 'viem/tempo';
import { parseAccount } from 'viem/utils';
import { getConnectorClient } from '../../actions/getConnectorClient.js';
import { filterQueryOptions } from './utils.js';
/**
* Gets information about the currently stored zone authorization token.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* await Actions.zone.signAuthorizationToken(config, {
* chainId: zoneChain.id,
* })
*
* const info = await Actions.zone.getAuthorizationTokenInfo(config, {
* chainId: zoneChain.id,
* })
*
* console.log(info.expiresAt)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The authorization token info.
*/
export function getAuthorizationTokenInfo(config, parameters) {
const client = config.getClient({ chainId: parameters.chainId });
return Actions.zone.getAuthorizationTokenInfo(client);
}
(function (getAuthorizationTokenInfo) {
function queryKey(parameters) {
return [
'getAuthorizationTokenInfo',
filterQueryOptions(parameters),
];
}
getAuthorizationTokenInfo.queryKey = queryKey;
function queryOptions(config, parameters) {
const { query, ...rest } = parameters;
return {
...query,
enabled: Boolean(query?.enabled ?? true),
queryKey: queryKey(rest),
async queryFn(context) {
const [, parameters] = context.queryKey;
return await getAuthorizationTokenInfo(config, parameters);
},
};
}
getAuthorizationTokenInfo.queryOptions = queryOptions;
})(getAuthorizationTokenInfo || (getAuthorizationTokenInfo = {}));
/**
* Gets the withdrawal fee for a given gas limit.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions } from '@wagmi/core/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const config = createConfig({
* chains: [zoneChain],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const fee = await Actions.zone.getWithdrawalFee(config, {
* chainId: zoneChain.id,
* callbackGas: 21_000n,
* })
*
* console.log(fee)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The withdrawal fee.
*/
export function getWithdrawalFee(config, parameters) {
const { chainId, ...rest } = parameters;
const client = config.getClient({ chainId });
return Actions.zone.getWithdrawalFee(client, rest);
}
(function (getWithdrawalFee) {
function queryKey(parameters) {
return ['getWithdrawalFee', filterQueryOptions(parameters)];
}
getWithdrawalFee.queryKey = queryKey;
function queryOptions(config, parameters) {
const { query, ...rest } = parameters;
return {
...query,
enabled: Boolean(query?.enabled ?? true),
queryKey: queryKey(rest),
async queryFn(context) {
const [, parameters] = context.queryKey;
return await getWithdrawalFee(config, parameters);
},
};
}
getWithdrawalFee.queryOptions = queryOptions;
})(getWithdrawalFee || (getWithdrawalFee = {}));
/**
* Gets the current zone metadata and latest imported Tempo block number.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions } from '@wagmi/core/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const config = createConfig({
* chains: [zoneChain],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const info = await Actions.zone.getZoneInfo(config, {
* chainId: zoneChain.id,
* })
*
* console.log(info.tempoBlockNumber)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The zone metadata and latest imported Tempo block number.
*/
export function getZoneInfo(config, parameters) {
const client = config.getClient({ chainId: parameters.chainId });
return Actions.zone.getZoneInfo(client);
}
(function (getZoneInfo) {
function queryKey(parameters) {
return ['getZoneInfo', filterQueryOptions(parameters)];
}
getZoneInfo.queryKey = queryKey;
function queryOptions(config, parameters) {
const { query, ...rest } = parameters;
return {
...query,
enabled: Boolean(query?.enabled ?? true),
queryKey: queryKey(rest),
async queryFn(context) {
const [, parameters] = context.queryKey;
return await getZoneInfo(config, parameters);
},
};
}
getZoneInfo.queryOptions = queryOptions;
})(getZoneInfo || (getZoneInfo = {}));
/**
* Waits for a zone to import a Tempo block.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions } from '@wagmi/core/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const config = createConfig({
* chains: [zoneChain],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const info = await Actions.zone.waitForTempoBlock(config, {
* chainId: zoneChain.id,
* tempoBlockNumber: 42n,
* })
*
* console.log(info.tempoBlockNumber)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The zone metadata after the block has been imported.
*/
export function waitForTempoBlock(config, parameters) {
const { chainId, ...rest } = parameters;
const client = config.getClient({ chainId });
return Actions.zone.waitForTempoBlock(client, rest);
}
(function (waitForTempoBlock) {
function queryKey(parameters) {
return ['waitForTempoBlock', filterQueryOptions(parameters)];
}
waitForTempoBlock.queryKey = queryKey;
function queryOptions(config, parameters) {
const { query, ...rest } = parameters;
return {
...query,
enabled: Boolean(rest.tempoBlockNumber !== undefined && (query?.enabled ?? true)),
queryKey: queryKey(rest),
async queryFn(context) {
const [, { tempoBlockNumber, ...parameters }] = context.queryKey;
if (tempoBlockNumber === undefined)
throw new Error('tempoBlockNumber is required.');
return await waitForTempoBlock(config, {
...parameters,
tempoBlockNumber,
});
},
};
}
waitForTempoBlock.queryOptions = queryOptions;
})(waitForTempoBlock || (waitForTempoBlock = {}));
/**
* Signs and stores a zone authorization token for the configured zone transport.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const result = await Actions.zone.signAuthorizationToken(config, {
* chainId: zoneChain.id,
* })
*
* console.log(result.token)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The authentication payload and serialized token.
*/
export async function signAuthorizationToken(config, parameters) {
const { account, chainId, connector, ...rest } = parameters;
const client = await getZoneWalletClient(config, {
account,
chainId,
connector,
});
return Actions.zone.signAuthorizationToken(client, rest);
}
/**
* Deposits tokens into a zone on the parent Tempo chain.
*
* @example
* ```ts
* import { createConfig, http } from '@wagmi/core'
* import { tempoModerato } from '@wagmi/core/chains'
* import { Actions } from '@wagmi/core/tempo'
*
* const config = createConfig({
* chains: [tempoModerato],
* transports: {
* [tempoModerato.id]: http(),
* },
* })
*
* const hash = await Actions.zone.deposit(config, {
* amount: 1_000_000n,
* token: '0x20c0000000000000000000000000000000000001',
* zoneId: 7,
* })
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns Transaction hash.
*/
export async function deposit(config, parameters) {
const { account, chainId, connector, ...rest } = parameters;
const client = await getConnectorClient(config, {
account,
assertChainId: false,
chainId,
connector,
});
const resolvedChainId = chainId ?? client.chain?.id;
if (!resolvedChainId)
throw new Error('`chainId` is required.');
const account_ = account ?? client.account;
if (!account_)
throw new Error('`account` is required.');
const accountAddress = parseAccount(account_).address;
const { amount, bouncebackRecipient, memo, portalAddress: portalAddress_, recipient = accountAddress, tempoRefundRecipient, token, zoneId, ...tx } = rest;
const portalAddress = portalAddress_ ?? resolvePortal(config, resolvedChainId, zoneId).address;
const refundRecipient = tempoRefundRecipient ?? bouncebackRecipient ?? accountAddress;
return viem_sendTransaction(client, {
...tx,
calls: Actions.zone.deposit.calls({
amount,
bouncebackRecipient: refundRecipient,
chainId: resolvedChainId,
memo,
portalAddress,
recipient,
tempoRefundRecipient: refundRecipient,
token,
zoneId,
}),
});
}
/**
* Deposits tokens into a zone on the parent Tempo chain.
*
* Note: This is a synchronous action that waits for the transaction to
* be included on a block before returning a response.
*
* @example
* ```ts
* import { createConfig, http } from '@wagmi/core'
* import { tempoModerato } from '@wagmi/core/chains'
* import { Actions } from '@wagmi/core/tempo'
*
* const config = createConfig({
* chains: [tempoModerato],
* transports: {
* [tempoModerato.id]: http(),
* },
* })
*
* const result = await Actions.zone.depositSync(config, {
* amount: 1_000_000n,
* token: '0x20c0000000000000000000000000000000000001',
* zoneId: 7,
* })
*
* console.log(result.receipt.transactionHash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The transaction receipt.
*/
export async function depositSync(config, parameters) {
const { account, chainId, connector, throwOnReceiptRevert = true, ...rest } = parameters;
const client = await getConnectorClient(config, {
account,
assertChainId: false,
chainId,
connector,
});
const resolvedChainId = chainId ?? client.chain?.id;
if (!resolvedChainId)
throw new Error('`chainId` is required.');
const account_ = account ?? client.account;
if (!account_)
throw new Error('`account` is required.');
const accountAddress = parseAccount(account_).address;
const { amount, bouncebackRecipient, memo, portalAddress: portalAddress_, recipient = accountAddress, tempoRefundRecipient, token, zoneId, ...tx } = rest;
const portalAddress = portalAddress_ ?? resolvePortal(config, resolvedChainId, zoneId).address;
const refundRecipient = tempoRefundRecipient ?? bouncebackRecipient ?? accountAddress;
const receipt = await viem_sendTransactionSync(client, {
...tx,
calls: Actions.zone.deposit.calls({
amount,
bouncebackRecipient: refundRecipient,
chainId: resolvedChainId,
memo,
portalAddress,
recipient,
tempoRefundRecipient: refundRecipient,
token,
zoneId,
}),
throwOnReceiptRevert,
});
return { receipt };
}
/**
* Deposits tokens into a zone on the parent Tempo chain with an encrypted
* recipient and memo.
*
* @example
* ```ts
* import { createConfig, http } from '@wagmi/core'
* import { tempoModerato } from '@wagmi/core/chains'
* import { Actions } from '@wagmi/core/tempo'
*
* const config = createConfig({
* chains: [tempoModerato],
* transports: {
* [tempoModerato.id]: http(),
* },
* })
*
* const hash = await Actions.zone.encryptedDeposit(config, {
* amount: 1_000_000n,
* token: '0x20c0000000000000000000000000000000000001',
* zoneId: 7,
* })
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns Transaction hash.
*/
export async function encryptedDeposit(config, parameters) {
const { account, chainId, connector, ...rest } = parameters;
const client = await getConnectorClient(config, {
account,
assertChainId: false,
chainId,
connector,
});
const resolvedChainId = chainId ?? client.chain?.id;
if (!resolvedChainId)
throw new Error('`chainId` is required.');
if ('encrypted' in rest)
return Actions.zone.encryptedDeposit(client, {
...rest,
chainId: resolvedChainId,
});
const portalAddress = rest.portalAddress ??
resolvePortal(config, resolvedChainId, rest.zoneId).address;
return Actions.zone.encryptedDeposit(client, {
...rest,
portalAddress,
});
}
/**
* Deposits tokens into a zone on the parent Tempo chain with an encrypted
* recipient and memo.
*
* Note: This is a synchronous action that waits for the transaction to
* be included on a block before returning a response.
*
* @example
* ```ts
* import { createConfig, http } from '@wagmi/core'
* import { tempoModerato } from '@wagmi/core/chains'
* import { Actions } from '@wagmi/core/tempo'
*
* const config = createConfig({
* chains: [tempoModerato],
* transports: {
* [tempoModerato.id]: http(),
* },
* })
*
* const result = await Actions.zone.encryptedDepositSync(config, {
* amount: 1_000_000n,
* token: '0x20c0000000000000000000000000000000000001',
* zoneId: 7,
* })
*
* console.log(result.receipt.transactionHash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The transaction receipt.
*/
export async function encryptedDepositSync(config, parameters) {
const { account, chainId, connector, throwOnReceiptRevert = true, ...rest } = parameters;
const client = await getConnectorClient(config, {
account,
assertChainId: false,
chainId,
connector,
});
const resolvedChainId = chainId ?? client.chain?.id;
if (!resolvedChainId)
throw new Error('`chainId` is required.');
if ('encrypted' in rest)
return Actions.zone.encryptedDepositSync(client, {
...rest,
chainId: resolvedChainId,
throwOnReceiptRevert,
});
const portalAddress = rest.portalAddress ??
resolvePortal(config, resolvedChainId, rest.zoneId).address;
return Actions.zone.encryptedDepositSync(client, {
...rest,
portalAddress,
throwOnReceiptRevert,
});
}
/**
* Requests a withdrawal from a zone to the parent Tempo chain.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const hash = await Actions.zone.requestWithdrawal(config, {
* amount: 1_000_000n,
* chainId: zoneChain.id,
* token: '0x20c0000000000000000000000000000000000001',
* })
*
* console.log(hash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns Transaction hash.
*/
export async function requestWithdrawal(config, parameters) {
const { account, chainId, connector } = parameters;
const client = await getZoneWalletClient(config, {
account,
chainId,
connector,
});
return Actions.zone.requestWithdrawal(client, parameters);
}
/**
* Requests a withdrawal from a zone to the parent Tempo chain.
*
* Note: This is a synchronous action that waits for the transaction to
* be included on a block before returning a response.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const result = await Actions.zone.requestWithdrawalSync(config, {
* amount: 1_000_000n,
* chainId: zoneChain.id,
* token: '0x20c0000000000000000000000000000000000001',
* })
*
* console.log(result.receipt.transactionHash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The transaction receipt.
*/
export async function requestWithdrawalSync(config, parameters) {
const { account, chainId, connector } = parameters;
const client = await getZoneWalletClient(config, {
account,
chainId,
connector,
});
return Actions.zone.requestWithdrawalSync(client, parameters);
}
/**
* Requests a verifiable withdrawal from a zone to the parent Tempo chain.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const hash = await Actions.zone.requestVerifiableWithdrawal(config, {
* amount: 1_000_000n,
* chainId: zoneChain.id,
* revealTo:
* '0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
* token: '0x20c0000000000000000000000000000000000001',
* })
*
* console.log(hash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns Transaction hash.
*/
export async function requestVerifiableWithdrawal(config, parameters) {
const { account, chainId, connector } = parameters;
const client = await getZoneWalletClient(config, {
account,
chainId,
connector,
});
return Actions.zone.requestVerifiableWithdrawal(client, parameters);
}
/**
* Requests a verifiable withdrawal from a zone to the parent Tempo chain.
*
* Note: This is a synchronous action that waits for the transaction to
* be included on a block before returning a response.
*
* @example
* ```ts
* import { createConfig } from '@wagmi/core'
* import { Actions, dangerous_secp256k1 } from '@wagmi/core/tempo'
* import { Account } from 'viem/tempo'
* import { http as zoneHttp, Zone } from 'viem/tempo'
*
* const zoneChain = Zone.b
* const account = Account.fromSecp256k1('0x...')
* const config = createConfig({
* chains: [zoneChain],
* connectors: [dangerous_secp256k1({ account })],
* transports: {
* [zoneChain.id]: zoneHttp(),
* },
* })
*
* const result = await Actions.zone.requestVerifiableWithdrawalSync(config, {
* amount: 1_000_000n,
* chainId: zoneChain.id,
* revealTo:
* '0x0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
* token: '0x20c0000000000000000000000000000000000001',
* })
*
* console.log(result.receipt.transactionHash)
* ```
*
* @param config - Config.
* @param parameters - Parameters.
* @returns The transaction receipt.
*/
export async function requestVerifiableWithdrawalSync(config, parameters) {
const { account, chainId, connector } = parameters;
const client = await getZoneWalletClient(config, {
account,
chainId,
connector,
});
return Actions.zone.requestVerifiableWithdrawalSync(client, parameters);
}
const portalAddresses = {
42431: {
6: '0x7069DeC4E64Fd07334A0933eDe836C17259c9B23',
7: '0x3F5296303400B56271b476F5A0B9cBF74350D6Ac',
},
};
async function getZoneWalletClient(config, parameters) {
const client = await getConnectorClient(config, {
...parameters,
assertChainId: false,
});
const resolvedChainId = parameters.chainId ?? client.chain?.id;
const account = resolveSignableAccount(parameters.account) ??
(await getSignableConnectorAccount(config, {
account: parameters.account ?? client.account,
chainId: resolvedChainId,
connector: parameters.connector,
}));
if (!account || resolvedChainId === undefined)
return client;
// Local accounts can sign against the zone transport directly without
// depending on the connector provider's currently selected chain.
return Object.assign(config.getClient({ chainId: resolvedChainId }), {
account,
});
}
async function getSignableConnectorAccount(config, parameters) {
const connector = parameters.connector ??
config.state.connections.get(config.state.current)?.connector;
const provider = (await connector?.getProvider?.({
chainId: parameters.chainId,
}));
if (typeof provider?.getAccount !== 'function')
return;
try {
return provider.getAccount({
address: parameters.account
? parseAccount(parameters.account).address
: undefined,
signable: true,
});
}
catch {
return;
}
}
function resolveSignableAccount(account) {
if (typeof account !== 'object' || account === null)
return;
return 'sign' in account ? account : undefined;
}
function resolvePortal(config, chainId, zoneId) {
const chain = config.chains.find((chain) => chain.id === chainId);
const zonePortal = chain?.contracts?.zonePortal;
// Allow custom chains to supply portal addresses until viem exposes a
// generic resolver for non-hardcoded Tempo networks.
if (typeof zonePortal === 'string')
return { address: zonePortal };
if (zonePortal && typeof zonePortal === 'object') {
const portal = 'address' in zonePortal && typeof zonePortal.address === 'string'
? zonePortal
: zonePortal[zoneId];
if (typeof portal === 'string')
return { address: portal };
if (portal &&
typeof portal === 'object' &&
typeof portal.address === 'string')
return { address: portal.address };
}
const address = portalAddresses[chainId]?.[zoneId];
if (address)
return { address };
throw new Error(`No portal address configured for zone ${zoneId} on chain ${chainId}.`);
}
//# sourceMappingURL=zone.js.map