@wagmi/core
Version:
VanillaJS library for Ethereum
1,242 lines (1,143 loc) • 35 kB
text/typescript
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}.`,
)
}