UNPKG

@wagmi/core

Version:

VanillaJS library for Ethereum

1,242 lines (1,143 loc) 35 kB
import type { Account, Address } from 'viem' 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 type { Config } from '../../createConfig.js' import type { ChainIdParameter, ConnectorParameter, } from '../../types/properties.js' import type { PartialBy, UnionLooseOmit } from '../../types/utils.js' import type { OptionalTransactionOverrides, QueryOptions, QueryParameter, } from './utils.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 extends Config>( config: config, parameters: getAuthorizationTokenInfo.Parameters<config>, ): Promise<getAuthorizationTokenInfo.ReturnValue> { const client = config.getClient({ chainId: parameters.chainId }) return Actions.zone.getAuthorizationTokenInfo(client) } export namespace getAuthorizationTokenInfo { export type Parameters<config extends Config> = ChainIdParameter<config> export type ReturnValue = Actions.zone.getAuthorizationTokenInfo.ReturnType export type ErrorType = Actions.zone.getAuthorizationTokenInfo.ErrorType export function queryKey<config extends Config>( parameters: Parameters<config>, ) { return [ 'getAuthorizationTokenInfo', filterQueryOptions(parameters), ] as const } export type QueryKey<config extends Config> = ReturnType< typeof queryKey<config> > export function queryOptions<config extends Config, selectData = ReturnValue>( config: Config, parameters: queryOptions.Parameters<config, selectData>, ): queryOptions.ReturnValue<config, selectData> { 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) }, } } export declare namespace queryOptions { export type Parameters< config extends Config, selectData = getAuthorizationTokenInfo.ReturnValue, > = getAuthorizationTokenInfo.Parameters<config> & QueryParameter< getAuthorizationTokenInfo.ReturnValue, getAuthorizationTokenInfo.ErrorType, selectData, getAuthorizationTokenInfo.QueryKey<config> > export type ReturnValue< config extends Config, selectData = getAuthorizationTokenInfo.ReturnValue, > = QueryOptions< getAuthorizationTokenInfo.ReturnValue, getAuthorizationTokenInfo.ErrorType, selectData, getAuthorizationTokenInfo.QueryKey<config> > } } /** * 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 extends Config>( config: config, parameters: getWithdrawalFee.Parameters<config>, ): Promise<getWithdrawalFee.ReturnValue> { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) return Actions.zone.getWithdrawalFee(client, rest) } export namespace getWithdrawalFee { export type Parameters<config extends Config> = ChainIdParameter<config> & Actions.zone.getWithdrawalFee.Parameters export type ReturnValue = Actions.zone.getWithdrawalFee.ReturnType export type ErrorType = Actions.zone.getWithdrawalFee.ErrorType export function queryKey<config extends Config>( parameters: Parameters<config>, ) { return ['getWithdrawalFee', filterQueryOptions(parameters)] as const } export type QueryKey<config extends Config> = ReturnType< typeof queryKey<config> > export function queryOptions<config extends Config, selectData = ReturnValue>( config: Config, parameters: queryOptions.Parameters<config, selectData>, ): queryOptions.ReturnValue<config, selectData> { 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) }, } } export declare namespace queryOptions { export type Parameters< config extends Config, selectData = getWithdrawalFee.ReturnValue, > = getWithdrawalFee.Parameters<config> & QueryParameter< getWithdrawalFee.ReturnValue, getWithdrawalFee.ErrorType, selectData, getWithdrawalFee.QueryKey<config> > export type ReturnValue< config extends Config, selectData = getWithdrawalFee.ReturnValue, > = QueryOptions< getWithdrawalFee.ReturnValue, getWithdrawalFee.ErrorType, selectData, getWithdrawalFee.QueryKey<config> > } } /** * 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 extends Config>( config: config, parameters: getZoneInfo.Parameters<config>, ): Promise<getZoneInfo.ReturnValue> { const client = config.getClient({ chainId: parameters.chainId }) return Actions.zone.getZoneInfo(client) } export namespace getZoneInfo { export type Parameters<config extends Config> = ChainIdParameter<config> export type ReturnValue = Actions.zone.getZoneInfo.ReturnType export type ErrorType = Actions.zone.getZoneInfo.ErrorType export function queryKey<config extends Config>( parameters: Parameters<config>, ) { return ['getZoneInfo', filterQueryOptions(parameters)] as const } export type QueryKey<config extends Config> = ReturnType< typeof queryKey<config> > export function queryOptions<config extends Config, selectData = ReturnValue>( config: Config, parameters: queryOptions.Parameters<config, selectData>, ): queryOptions.ReturnValue<config, selectData> { 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) }, } } export declare namespace queryOptions { export type Parameters< config extends Config, selectData = getZoneInfo.ReturnValue, > = getZoneInfo.Parameters<config> & QueryParameter< getZoneInfo.ReturnValue, getZoneInfo.ErrorType, selectData, getZoneInfo.QueryKey<config> > export type ReturnValue< config extends Config, selectData = getZoneInfo.ReturnValue, > = QueryOptions< getZoneInfo.ReturnValue, getZoneInfo.ErrorType, selectData, getZoneInfo.QueryKey<config> > } } /** * 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 extends Config>( config: config, parameters: waitForTempoBlock.Parameters<config>, ): Promise<waitForTempoBlock.ReturnValue> { const { chainId, ...rest } = parameters const client = config.getClient({ chainId }) return Actions.zone.waitForTempoBlock(client, rest) } export namespace waitForTempoBlock { export type Parameters<config extends Config> = ChainIdParameter<config> & Actions.zone.waitForTempoBlock.Parameters export type ReturnValue = Actions.zone.waitForTempoBlock.ReturnType export type ErrorType = Actions.zone.waitForTempoBlock.ErrorType export function queryKey<config extends Config>( parameters: PartialBy<Parameters<config>, 'tempoBlockNumber'>, ) { return ['waitForTempoBlock', filterQueryOptions(parameters)] as const } export type QueryKey<config extends Config> = ReturnType< typeof queryKey<config> > export function queryOptions<config extends Config, selectData = ReturnValue>( config: Config, parameters: queryOptions.Parameters<config, selectData>, ): queryOptions.ReturnValue<config, selectData> { 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, }) }, } } export declare namespace queryOptions { export type Parameters< config extends Config, selectData = waitForTempoBlock.ReturnValue, > = PartialBy<waitForTempoBlock.Parameters<config>, 'tempoBlockNumber'> & QueryParameter< waitForTempoBlock.ReturnValue, waitForTempoBlock.ErrorType, selectData, waitForTempoBlock.QueryKey<config> > export type ReturnValue< config extends Config, selectData = waitForTempoBlock.ReturnValue, > = QueryOptions< waitForTempoBlock.ReturnValue, waitForTempoBlock.ErrorType, selectData, waitForTempoBlock.QueryKey<config> > } } /** * 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 extends Config>( config: config, parameters: signAuthorizationToken.Parameters<config>, ): Promise<signAuthorizationToken.ReturnValue> { const { account, chainId, connector, ...rest } = parameters const client = await getZoneWalletClient(config, { account, chainId, connector, }) return Actions.zone.signAuthorizationToken(client, rest as never) } export declare namespace signAuthorizationToken { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & { account?: Address | Account | undefined } & UnionLooseOmit< Actions.zone.signAuthorizationToken.Parameters<Account>, 'account' | 'chain' > export type ReturnValue = Actions.zone.signAuthorizationToken.ReturnType export type ErrorType = Actions.zone.signAuthorizationToken.ErrorType } /** * 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 extends Config>( config: config, parameters: deposit.Parameters<config>, ): Promise<deposit.ReturnValue> { 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 as typeof rest & { bouncebackRecipient?: Address | undefined tempoRefundRecipient?: Address | undefined } 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, } as never), } as never) as never } export declare namespace deposit { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.deposit.Parameters<config['chains'][number], Account> >, 'chain' > export type ReturnValue = Actions.zone.deposit.ReturnValue export type ErrorType = Actions.zone.deposit.ErrorType } /** * 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 extends Config>( config: config, parameters: depositSync.Parameters<config>, ): Promise<depositSync.ReturnValue> { 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 as typeof rest & { bouncebackRecipient?: Address | undefined tempoRefundRecipient?: Address | undefined } 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, } as never), throwOnReceiptRevert, } as never) return { receipt } } export declare namespace depositSync { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.depositSync.Parameters<config['chains'][number], Account> >, 'chain' > export type ReturnValue = Actions.zone.depositSync.ReturnValue export type ErrorType = Actions.zone.depositSync.ErrorType } /** * 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 extends Config>( config: config, parameters: encryptedDeposit.Parameters<config>, ): Promise<encryptedDeposit.ReturnValue> { 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, } as never) const portalAddress = rest.portalAddress ?? resolvePortal(config, resolvedChainId, rest.zoneId).address return Actions.zone.encryptedDeposit(client, { ...rest, portalAddress, } as never) } export declare namespace encryptedDeposit { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.encryptedDeposit.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.encryptedDeposit.ReturnValue export type ErrorType = Actions.zone.encryptedDeposit.ErrorType } /** * 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 extends Config>( config: config, parameters: encryptedDepositSync.Parameters<config>, ): Promise<encryptedDepositSync.ReturnValue> { 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, } as never) const portalAddress = rest.portalAddress ?? resolvePortal(config, resolvedChainId, rest.zoneId).address return Actions.zone.encryptedDepositSync(client, { ...rest, portalAddress, throwOnReceiptRevert, } as never) } export declare namespace encryptedDepositSync { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.encryptedDepositSync.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.encryptedDepositSync.ReturnValue export type ErrorType = Actions.zone.encryptedDepositSync.ErrorType } /** * 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 extends Config>( config: config, parameters: requestWithdrawal.Parameters<config>, ): Promise<requestWithdrawal.ReturnValue> { const { account, chainId, connector } = parameters const client = await getZoneWalletClient(config, { account, chainId, connector, }) return Actions.zone.requestWithdrawal(client, parameters as never) } export declare namespace requestWithdrawal { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.requestWithdrawal.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.requestWithdrawal.ReturnValue export type ErrorType = Actions.zone.requestWithdrawal.ErrorType } /** * 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 extends Config>( config: config, parameters: requestWithdrawalSync.Parameters<config>, ): Promise<requestWithdrawalSync.ReturnValue> { const { account, chainId, connector } = parameters const client = await getZoneWalletClient(config, { account, chainId, connector, }) return Actions.zone.requestWithdrawalSync(client, parameters as never) } export declare namespace requestWithdrawalSync { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.requestWithdrawalSync.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.requestWithdrawalSync.ReturnValue export type ErrorType = Actions.zone.requestWithdrawalSync.ErrorType } /** * 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 extends Config>( config: config, parameters: requestVerifiableWithdrawal.Parameters<config>, ): Promise<requestVerifiableWithdrawal.ReturnValue> { const { account, chainId, connector } = parameters const client = await getZoneWalletClient(config, { account, chainId, connector, }) return Actions.zone.requestVerifiableWithdrawal(client, parameters as never) } export declare namespace requestVerifiableWithdrawal { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.requestVerifiableWithdrawal.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.requestVerifiableWithdrawal.ReturnValue export type ErrorType = Actions.zone.requestVerifiableWithdrawal.ErrorType } /** * 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 extends Config>( config: config, parameters: requestVerifiableWithdrawalSync.Parameters<config>, ): Promise<requestVerifiableWithdrawalSync.ReturnValue> { const { account, chainId, connector } = parameters const client = await getZoneWalletClient(config, { account, chainId, connector, }) return Actions.zone.requestVerifiableWithdrawalSync( client, parameters as never, ) } export declare namespace requestVerifiableWithdrawalSync { export type Parameters<config extends Config> = ChainIdParameter<config> & ConnectorParameter & UnionLooseOmit< OptionalTransactionOverrides< Actions.zone.requestVerifiableWithdrawalSync.Parameters< config['chains'][number], Account > >, 'chain' > export type ReturnValue = Actions.zone.requestVerifiableWithdrawalSync.ReturnValue export type ErrorType = Actions.zone.requestVerifiableWithdrawalSync.ErrorType } const portalAddresses = { 42431: { 6: '0x7069DeC4E64Fd07334A0933eDe836C17259c9B23', 7: '0x3F5296303400B56271b476F5A0B9cBF74350D6Ac', }, } as const satisfies Record<number, Record<number, Address>> async function getZoneWalletClient<config extends Config>( config: config, parameters: { account?: Address | Account | null | undefined chainId?: number | undefined connector?: ConnectorParameter['connector'] }, ) { 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, }) as typeof client } async function getSignableConnectorAccount<config extends Config>( config: config, parameters: { account?: Address | Account | null | undefined chainId?: number | undefined connector?: ConnectorParameter['connector'] }, ) { const connector = parameters.connector ?? config.state.connections.get(config.state.current!)?.connector const provider = (await connector?.getProvider?.({ chainId: parameters.chainId, })) as | { getAccount?: | ((parameters?: { address?: Address | undefined signable?: boolean | undefined }) => Account | undefined) | undefined } | undefined 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?: Address | Account | null | undefined, ) { if (typeof account !== 'object' || account === null) return return 'sign' in account ? account : undefined } function resolvePortal<config extends Config>( config: config, chainId: number, zoneId: number, ): { address: Address } { const chain = config.chains.find((chain) => chain.id === chainId) const zonePortal = chain?.contracts?.zonePortal as | Address | { [key: number]: | Address | { address?: Address | undefined } | undefined address?: Address | undefined } | undefined // 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 as Address } if ( portal && typeof portal === 'object' && typeof portal.address === 'string' ) return { address: portal.address } } const address = (portalAddresses as Record<number, Record<number, Address>>)[ chainId ]?.[zoneId] if (address) return { address } throw new Error( `No portal address configured for zone ${zoneId} on chain ${chainId}.`, ) }