Skip to content

Quickstart

Union Private Payments enables privacy-preserving token transfers using zero-knowledge proofs. When you send a payment through Union:

  1. Sender privacy: The outside world cannot see which senders sent funds to which receivers.
  2. Amount privacy: Transfer amounts are obfuscated.
  3. Unlinkability: Blockchain explorers cannot trace the flow of funds, and given a sufficient anonymity set, neither can analytics tools.

The system works by:

  • Wrapping ERC20 tokens into privacy-preserving ZAssets
  • Transferring to cryptographically-derived “unspendable” addresses
  • Using zero-knowledge proofs to verify balances without revealing the sender
  • Redeeming funds to designated beneficiaries with attestation verification

The paymentKey is a 32-byte secret that serves as the core of the privacy system. It is used to:

  • Derive the unspendable deposit address (where funds are held privately)
  • Compute the nullifier (prevents double-spending)
  • Generate proofs for redemption

When creating a deposit, you may specify up to 4 beneficiary addresses. These are cryptographically bound to the deposit such that:

  • only these addresses can receive the funds upon redemption,
  • the beneficiaries cannot be changed after deposit,
  • theft is prevented even if the payment key is compromised, and
  • the anonymity set is increased.

Install the Union Private Payments SDK using pnpm:

Terminal window
pnpm install @unionlabs/payments

The SDK requires viem as a peer dependency for EVM interactions:

Terminal window
pnpm install viem

Construct a transfer (and a zero knowledge proof)

Section titled “Construct a transfer (and a zero knowledge proof)”

First, we’ll set up all the clients needed for private payments. The SDK provides a Promise-based API that wraps the underlying Effect-based implementation.

import {
import Domain
Domain
,
import IbcCoreRegistry
IbcCoreRegistry
} from "@unionlabs/payments";
import {
import Attestor
Attestor
,
import EvmPublicClient
EvmPublicClient
,
import EvmWalletClient
EvmWalletClient
,
import Payment
Payment
,
import Prover
Prover
,
} from "@unionlabs/payments/promises";
import * as
import Viem
Viem
from "viem";
import * as
import ViemAccounts
ViemAccounts
from "viem/accounts";
import * as
import ViemChains
ViemChains
from "viem/chains";
const
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
= "https://base-mainnet.g.alchemy.com/v2/<redacted>";
const
const ATTESTOR_KEY: string
ATTESTOR_KEY
=
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

Terminal window
node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
ATTESTOR_KEY
??
"6af6f8068d38ebf6666b8db98f9b8b42959ab62646764bc290e663f7abb49eea";
const
const BENEFICIARY: Domain.Erc20Address
BENEFICIARY
=
import Domain
Domain
.
const Erc20Address: Brand<in out K extends string | symbol>.Constructor
(args: `0x${string}`) => Domain.Erc20Address

Constructs a branded type from a value of type A, throwing an error if the provided A is not valid.

Erc20Address
(
"0x06627714f3f17a701f7074a12c02847a5d2ca487",
);
const
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
=
import Domain
Domain
.
const Erc20Address: Brand<in out K extends string | symbol>.Constructor
(args: `0x${string}`) => Domain.Erc20Address

Constructs a branded type from a value of type A, throwing an error if the provided A is not valid.

Erc20Address
(
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
);
const
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
=
import Domain
Domain
.
const UniversalChainId: brand<filter<typeof String$>, "UniversalChainId">
UniversalChainId
.
BrandSchema<string & Brand<"UniversalChainId">, string, never>.make(a: string, options?: MakeOptions): string & Brand<"UniversalChainId">
make
("base.8453");
const
const privateKey: `0x${string}`
privateKey
=
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

Terminal window
node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
PRIVATE_KEY
as `0x${string}`;
if (!
const privateKey: `0x${string}`
privateKey
) throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
("Please provide a PRIVATE_KEY as an env var.");

Create Viem clients for blockchain interactions:

const
const viemPublicClient: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<Viem.PublicRpcSchema>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemPublicClient
=
import Viem
Viem
.
createPublicClient<Viem.HttpTransport<undefined, false>, {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}, undefined, []>(parameters: {
...;
}): {
...;
}
export createPublicClient

Creates a Public Client with a given Transport configured for a Chain.

A Public Client is an interface to "public" JSON-RPC API methods such as retrieving block numbers, transactions, reading from smart contracts, etc through Public Actions.

@paramconfig - PublicClientConfig

@returnsA Public Client. PublicClient

@example

import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(), })

createPublicClient
({
chain?: Viem.Chain | {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
} | undefined

Chain for the client.

chain
:
import ViemChains
ViemChains
.
const base: {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}
export base
base
,
transport: Viem.HttpTransport<undefined, false>

The RPC transport

transport
:
import Viem
Viem
.
http<undefined, false>(url?: string | undefined, config?: Viem.HttpTransportConfig<undefined, false> | undefined): Viem.HttpTransport<undefined, false>
export http

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
(
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
),
}) as
import Viem
Viem
.
type PublicClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, accountOrAddress extends Account | undefined = undefined, rpcSchema extends RpcSchema | undefined = undefined> = {
account: accountOrAddress;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: chain;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<...>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
export PublicClient
PublicClient
;
const
const viemWalletClient: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemWalletClient
=
import Viem
Viem
.
createWalletClient<Viem.HttpTransport<undefined, false>, {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}, {
...;
}, []>(parameters: {
...;
}): {
...;
}
export createWalletClient

Creates a Wallet Client with a given Transport configured for a Chain.

A Wallet Client is an interface to interact with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc. through Wallet Actions.

The Wallet Client supports signing over:

@paramconfig - WalletClientConfig

@returnsA Wallet Client. WalletClient

@example

// JSON-RPC Account import { createWalletClient, custom } from 'viem' import { mainnet } from 'viem/chains'

const client = createWalletClient({ chain: mainnet, transport: custom(window.ethereum), })

@example

// Local Account import { createWalletClient, custom } from 'viem' import { privateKeyToAccount } from 'viem/accounts' import { mainnet } from 'viem/chains'

const client = createWalletClient({ account: privateKeyToAccount('0x…') chain: mainnet, transport: http(), })

createWalletClient
({
account?: `0x${string}` | {
address: Viem.Address;
nonceManager?: Viem.NonceManager | undefined;
sign: (parameters: {
hash: Viem.Hash;
}) => Promise<Viem.Hex>;
signAuthorization: (parameters: Viem.AuthorizationRequest) => Promise<ViemAccounts.SignAuthorizationReturnType>;
signMessage: ({ message }: {
message: Viem.SignableMessage;
}) => Promise<Viem.Hex>;
signTransaction: <serializer extends Viem.SerializeTransactionFn<Viem.TransactionSerializable> = Viem.SerializeTransactionFn<Viem.TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
serializer?: serializer | undefined;
} | undefined) => Promise<Viem.Hex>;
signTypedData: <const typedData extends Viem.TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: Viem.TypedDataDefinition<typedData, primaryType>) => Promise<Viem.Hex>;
publicKey: Viem.Hex;
source: "privateKey";
type: "local";
} | Viem.Account | undefined

The Account to use for the Client. This will be used for Actions that require an account as an argument.

account
:
import ViemAccounts
ViemAccounts
.
function privateKeyToAccount(privateKey: Viem.Hex, options?: ViemAccounts.PrivateKeyToAccountOptions): Viem.PrivateKeyAccount
export privateKeyToAccount

@description Creates an Account from a private key.

@returnsA Private Key Account.

privateKeyToAccount
(
const privateKey: `0x${string}`
privateKey
),
chain?: Viem.Chain | {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
} | undefined

Chain for the client.

chain
:
import ViemChains
ViemChains
.
const base: {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}
export base
base
,
transport: Viem.HttpTransport<undefined, false>

The RPC transport

transport
:
import Viem
Viem
.
http<undefined, false>(url?: string | undefined, config?: Viem.HttpTransportConfig<undefined, false> | undefined): Viem.HttpTransport<undefined, false>
export http

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
(
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
),
}) as
import Viem
Viem
.
type WalletClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends Account | undefined = Account | undefined, rpcSchema extends RpcSchema | undefined = undefined> = {
account: account;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: chain;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<(rpcSchema extends Viem.RpcSchema ? [...] : Viem.WalletRpcSchema) extends undefined ? [...] : rpcSchema extends Viem.RpcSchema ? [...] : Viem.WalletRpcSchema>;
... 30 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
export WalletClient
WalletClient
;

Wrap Viem clients with the SDK’s typed clients:

const
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
= await
import EvmWalletClient
EvmWalletClient
.
const fromViem: (config: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <client>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}) => Promise<...>
fromViem
(
const viemWalletClient: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemWalletClient
);
const
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
= await
import EvmPublicClient
EvmPublicClient
.
const fromViem: (config: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<...>;
... 59 more ...;
extend: <client>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}) => Promise<...>
fromViem
(
const viemPublicClient: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<Viem.PublicRpcSchema>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemPublicClient
);

Initialize the Attestor and Prover services:

Message: Attestor signs beneficiary attestations
const
const attestor: Attestor.Attestor
attestor
= await
import Attestor
Attestor
.
const make: (options: Parameters<(options: {
readonly apiKey: string;
readonly baseUrl?: string | URL | undefined;
}) => Layer<Attestor, SystemError, never>>[0]) => Promise<Attestor.Attestor>
make
({
apiKey: string
apiKey
:
const ATTESTOR_KEY: string
ATTESTOR_KEY
});
Message: Prover generates zero-knowledge proofs
const
const prover: Prover.Prover
prover
= await
import Prover
Prover
.
const make: (options: Parameters<(options: {
readonly proverUrl?: string | URL | undefined;
}) => Layer<Prover, SystemError, never>>[0]) => Promise<Prover.Prover>
make
({});
import {
import Domain
Domain
,
import IbcCoreRegistry
IbcCoreRegistry
} from "@unionlabs/payments";
import {
import Attestor
Attestor
,
import EvmPublicClient
EvmPublicClient
,
import EvmWalletClient
EvmWalletClient
,
import Payment
Payment
,
import Prover
Prover
,
} from "@unionlabs/payments/promises";
import * as
import Viem
Viem
from "viem";
import * as
import ViemAccounts
ViemAccounts
from "viem/accounts";
import * as
import ViemChains
ViemChains
from "viem/chains";
const
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
= "https://base-mainnet.g.alchemy.com/v2/<redacted>";
const
const ATTESTOR_KEY: string
ATTESTOR_KEY
=
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

Terminal window
node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
ATTESTOR_KEY
??
"6af6f8068d38ebf6666b8db98f9b8b42959ab62646764bc290e663f7abb49eea";
const
const BENEFICIARY: Domain.Erc20Address
BENEFICIARY
=
import Domain
Domain
.
const Erc20Address: Brand<in out K extends string | symbol>.Constructor
(args: `0x${string}`) => Domain.Erc20Address

Constructs a branded type from a value of type A, throwing an error if the provided A is not valid.

Erc20Address
(
"0x06627714f3f17a701f7074a12c02847a5d2ca487",
);
const
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
=
import Domain
Domain
.
const Erc20Address: Brand<in out K extends string | symbol>.Constructor
(args: `0x${string}`) => Domain.Erc20Address

Constructs a branded type from a value of type A, throwing an error if the provided A is not valid.

Erc20Address
(
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
);
const
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
=
import Domain
Domain
.
const UniversalChainId: brand<filter<typeof String$>, "UniversalChainId">
UniversalChainId
.
BrandSchema<string & Brand<"UniversalChainId">, string, never>.make(a: string, options?: MakeOptions): string & Brand<"UniversalChainId">
make
("base.8453");
const
const privateKey: `0x${string}`
privateKey
=
var process: NodeJS.Process
process
.
NodeJS.Process.env: NodeJS.ProcessEnv

The process.env property returns an object containing the user environment. See environ(7).

An example of this object looks like:

{
TERM: 'xterm-256color',
SHELL: '/usr/local/bin/bash',
USER: 'maciej',
PATH: '~/.bin/:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin',
PWD: '/Users/maciej',
EDITOR: 'vim',
SHLVL: '1',
HOME: '/Users/maciej',
LOGNAME: 'maciej',
_: '/usr/local/bin/node'
}

It is possible to modify this object, but such modifications will not be reflected outside the Node.js process, or (unless explicitly requested) to other Worker threads. In other words, the following example would not work:

Terminal window
node -e 'process.env.foo = "bar"' &#x26;&#x26; echo $foo

While the following will:

import { env } from 'node:process';
env.foo = 'bar';
console.log(env.foo);

Assigning a property on process.env will implicitly convert the value to a string. This behavior is deprecated. Future versions of Node.js may throw an error when the value is not a string, number, or boolean.

import { env } from 'node:process';
env.test = null;
console.log(env.test);
// => 'null'
env.test = undefined;
console.log(env.test);
// => 'undefined'

Use delete to delete a property from process.env.

import { env } from 'node:process';
env.TEST = 1;
delete env.TEST;
console.log(env.TEST);
// => undefined

On Windows operating systems, environment variables are case-insensitive.

import { env } from 'node:process';
env.TEST = 1;
console.log(env.test);
// => 1

Unless explicitly specified when creating a Worker instance, each Worker thread has its own copy of process.env, based on its parent thread's process.env, or whatever was specified as the env option to the Worker constructor. Changes to process.env will not be visible across Worker threads, and only the main thread can make changes that are visible to the operating system or to native add-ons. On Windows, a copy of process.env on a Worker instance operates in a case-sensitive manner unlike the main thread.

@sincev0.1.27

env
.
string | undefined
PRIVATE_KEY
as `0x${string}`;
if (!
const privateKey: `0x${string}`
privateKey
) throw new
var Error: ErrorConstructor
new (message?: string, options?: ErrorOptions) => Error (+1 overload)
Error
("Please provide a PRIVATE_KEY as an env var.");
const
const viemPublicClient: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<Viem.PublicRpcSchema>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemPublicClient
=
import Viem
Viem
.
createPublicClient<Viem.HttpTransport<undefined, false>, {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}, undefined, []>(parameters: {
...;
}): {
...;
}
export createPublicClient

Creates a Public Client with a given Transport configured for a Chain.

A Public Client is an interface to "public" JSON-RPC API methods such as retrieving block numbers, transactions, reading from smart contracts, etc through Public Actions.

@paramconfig - PublicClientConfig

@returnsA Public Client. PublicClient

@example

import { createPublicClient, http } from 'viem' import { mainnet } from 'viem/chains'

const client = createPublicClient({ chain: mainnet, transport: http(), })

createPublicClient
({
chain?: Viem.Chain | {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
} | undefined

Chain for the client.

chain
:
import ViemChains
ViemChains
.
const base: {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}
export base
base
,
transport: Viem.HttpTransport<undefined, false>

The RPC transport

transport
:
import Viem
Viem
.
http<undefined, false>(url?: string | undefined, config?: Viem.HttpTransportConfig<undefined, false> | undefined): Viem.HttpTransport<undefined, false>
export http

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
(
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
),
}) as
import Viem
Viem
.
type PublicClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, accountOrAddress extends Account | undefined = undefined, rpcSchema extends RpcSchema | undefined = undefined> = {
account: accountOrAddress;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: chain;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<...>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
export PublicClient
PublicClient
;
const
const viemWalletClient: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemWalletClient
=
import Viem
Viem
.
createWalletClient<Viem.HttpTransport<undefined, false>, {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}, {
...;
}, []>(parameters: {
...;
}): {
...;
}
export createWalletClient

Creates a Wallet Client with a given Transport configured for a Chain.

A Wallet Client is an interface to interact with Ethereum Account(s) and provides the ability to retrieve accounts, execute transactions, sign messages, etc. through Wallet Actions.

The Wallet Client supports signing over:

@paramconfig - WalletClientConfig

@returnsA Wallet Client. WalletClient

@example

// JSON-RPC Account import { createWalletClient, custom } from 'viem' import { mainnet } from 'viem/chains'

const client = createWalletClient({ chain: mainnet, transport: custom(window.ethereum), })

@example

// Local Account import { createWalletClient, custom } from 'viem' import { privateKeyToAccount } from 'viem/accounts' import { mainnet } from 'viem/chains'

const client = createWalletClient({ account: privateKeyToAccount('0x…') chain: mainnet, transport: http(), })

createWalletClient
({
account?: `0x${string}` | {
address: Viem.Address;
nonceManager?: Viem.NonceManager | undefined;
sign: (parameters: {
hash: Viem.Hash;
}) => Promise<Viem.Hex>;
signAuthorization: (parameters: Viem.AuthorizationRequest) => Promise<ViemAccounts.SignAuthorizationReturnType>;
signMessage: ({ message }: {
message: Viem.SignableMessage;
}) => Promise<Viem.Hex>;
signTransaction: <serializer extends Viem.SerializeTransactionFn<Viem.TransactionSerializable> = Viem.SerializeTransactionFn<Viem.TransactionSerializable>, transaction extends Parameters<serializer>[0] = Parameters<serializer>[0]>(transaction: transaction, options?: {
serializer?: serializer | undefined;
} | undefined) => Promise<Viem.Hex>;
signTypedData: <const typedData extends Viem.TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData>(parameters: Viem.TypedDataDefinition<typedData, primaryType>) => Promise<Viem.Hex>;
publicKey: Viem.Hex;
source: "privateKey";
type: "local";
} | Viem.Account | undefined

The Account to use for the Client. This will be used for Actions that require an account as an argument.

account
:
import ViemAccounts
ViemAccounts
.
function privateKeyToAccount(privateKey: Viem.Hex, options?: ViemAccounts.PrivateKeyToAccountOptions): Viem.PrivateKeyAccount
export privateKeyToAccount

@description Creates an Account from a private key.

@returnsA Private Key Account.

privateKeyToAccount
(
const privateKey: `0x${string}`
privateKey
),
chain?: Viem.Chain | {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
} | undefined

Chain for the client.

chain
:
import ViemChains
ViemChains
.
const base: {
blockExplorers: {
readonly default: {
readonly name: "Basescan";
readonly url: "https://basescan.org";
readonly apiUrl: "https://api.basescan.org/api";
};
};
blockTime: 2000;
contracts: {
readonly disputeGameFactory: {
readonly 1: {
readonly address: "0x43edB88C4B80fDD2AdFF2412A7BebF9dF42cB40e";
};
};
readonly l2OutputOracle: {
readonly 1: {
readonly address: "0x56315b90c40730925ec5485cf004d835058518A0";
};
};
readonly multicall3: {
readonly address: "0xca11bde05977b3631167028862be2a173976ca11";
readonly blockCreated: 5022;
};
readonly portal: {
readonly 1: {
readonly address: "0x49048044D57e1C92A77f79988d21Fa8fAF74E97e";
readonly blockCreated: 17482143;
};
};
readonly l1StandardBridge: {
readonly 1: {
readonly address: "0x3154Cf16ccdb4C6d922629664174b904d80F2C35";
readonly blockCreated: 17482143;
};
};
readonly gasPriceOracle: {
readonly address: "0x420000000000000000000000000000000000000F";
};
readonly l1Block: {
readonly address: "0x4200000000000000000000000000000000000015";
};
readonly l2CrossDomainMessenger: {
readonly address: "0x4200000000000000000000000000000000000007";
};
readonly l2Erc721Bridge: {
readonly address: "0x4200000000000000000000000000000000000014";
};
readonly l2StandardBridge: {
readonly address: "0x4200000000000000000000000000000000000010";
};
readonly l2ToL1MessagePasser: {
readonly address: "0x4200000000000000000000000000000000000016";
};
};
... 11 more ...;
serializers: {
readonly transaction: (transaction: ViemChains.OpStackTransactionSerializable, signature?: Viem.Signature) => `0x02${string}` | `0x01${string}` | `0x03${string}` | `0x04${string}` | Viem.TransactionSerializedLegacy | `0x7e${string}`;
};
}
export base
base
,
transport: Viem.HttpTransport<undefined, false>

The RPC transport

transport
:
import Viem
Viem
.
http<undefined, false>(url?: string | undefined, config?: Viem.HttpTransportConfig<undefined, false> | undefined): Viem.HttpTransport<undefined, false>
export http

@description Creates a HTTP transport that connects to a JSON-RPC API.

http
(
const BASE_RPC: "https://base-mainnet.g.alchemy.com/v2/<redacted>"
BASE_RPC
),
}) as
import Viem
Viem
.
type WalletClient<transport extends Transport = Transport, chain extends Chain | undefined = Chain | undefined, account extends Account | undefined = Account | undefined, rpcSchema extends RpcSchema | undefined = undefined> = {
account: account;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: chain;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<(rpcSchema extends Viem.RpcSchema ? [...] : Viem.WalletRpcSchema) extends undefined ? [...] : rpcSchema extends Viem.RpcSchema ? [...] : Viem.WalletRpcSchema>;
... 30 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
export WalletClient
WalletClient
;
const
const sleep: (ms: number) => Promise<unknown>
sleep
= (
ms: number
ms
: number) => new
var Promise: PromiseConstructor
new <unknown>(executor: (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void) => Promise<unknown>

Creates a new Promise.

@paramexecutor A callback used to initialize the promise. This callback is passed two arguments: a resolve callback used to resolve the promise with a value or the result of another promise, and a reject callback used to reject the promise with a provided reason or error.

Promise
((
r: (value: unknown) => void
r
) =>
function setTimeout(callback: (_: void) => void, delay?: number): NodeJS.Timeout (+2 overloads)
setTimeout
(
r: (value: unknown) => void
r
,
ms: number
ms
));
async function
function main(): Promise<string>
main
() {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("0. Setting up clients...");
const
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
= await
import EvmWalletClient
EvmWalletClient
.
const fromViem: (config: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <client>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}) => Promise<...>
fromViem
(
const viemWalletClient: {
account: Viem.Account | undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
... 31 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemWalletClient
as unknown as any,
);
const
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
= await
import EvmPublicClient
EvmPublicClient
.
const fromViem: (config: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<...>;
... 59 more ...;
extend: <client>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}) => Promise<...>
fromViem
(
const viemPublicClient: {
account: undefined;
batch?: {
multicall?: boolean | Viem.Prettify<Viem.MulticallBatchOptions> | undefined;
} | undefined;
cacheTime: number;
ccipRead?: false | {
request?: (parameters: Viem.CcipRequestParameters) => Promise<CcipRequestReturnType>;
} | undefined;
chain: Viem.Chain | undefined;
experimental_blockTag?: Viem.BlockTag | undefined;
key: string;
name: string;
pollingInterval: number;
request: Viem.EIP1193RequestFn<Viem.PublicRpcSchema>;
... 59 more ...;
extend: <const client extends {
...;
} & Viem.ExactPartial<...>>(fn: (client: Viem.Client<...>) => client) => Viem.Client<...>;
}
viemPublicClient
as unknown as any,
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("0. Generate input data...");
const
const paymentKey: Domain.PaymentKey
paymentKey
= await
import Payment
Payment
.
const generateKey: () => Promise<Domain.PaymentKey>
generateKey
();
const
const depositAddress: {
beneficiaries: [Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address];
zAssetAddress: Domain.ZAssetAddress;
destinationChainId: string & Brand<"UniversalChainId">;
}
depositAddress
= await
import Payment
Payment
.
const getDepositAddress: (options: {
paymentKey: Domain.PaymentKey;
beneficiaries: ReadonlyArray<Domain.Erc20Address>;
destinationChainId: Domain.UniversalChainId;
}) => Promise<{
beneficiaries: [Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address];
zAssetAddress: Domain.ZAssetAddress;
destinationChainId: string & Brand<"UniversalChainId">;
}>
getDepositAddress
({
paymentKey: Domain.PaymentKey
paymentKey
,
beneficiaries: readonly Domain.Erc20Address[]
beneficiaries
: [
const BENEFICIARY: Domain.Erc20Address
BENEFICIARY
],
destinationChainId: string & Brand<"UniversalChainId">
destinationChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
});
const
const nullifier: Domain.Nullifier
nullifier
= await
import Payment
Payment
.
const getNullifier: (options: {
paymentKey: Domain.PaymentKey;
destinationChainId: Domain.UniversalChainId;
}) => Promise<Domain.Nullifier>
getNullifier
({
paymentKey: Domain.PaymentKey
paymentKey
,
destinationChainId: string & Brand<"UniversalChainId">
destinationChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
});
const
const attestor: Attestor.Attestor
attestor
= await
import Attestor
Attestor
.
const make: (options: Parameters<(options: {
readonly apiKey: string;
readonly baseUrl?: string | URL | undefined;
}) => Layer<Attestor, SystemError, never>>[0]) => Promise<Attestor.Attestor>
make
({
baseUrl?: string | URL | undefined
baseUrl
: "https://attestor.payments.union.build/functions/v1/attest",
apiKey: string
apiKey
:
const ATTESTOR_KEY: string
ATTESTOR_KEY
,
});
const
const prover: Prover.Prover
prover
= await
import Prover
Prover
.
const make: (options: Parameters<(options: {
readonly proverUrl?: string | URL | undefined;
}) => Layer<Prover, SystemError, never>>[0]) => Promise<Prover.Prover>
make
({
proverUrl?: string | URL | undefined
proverUrl
: "https://prover.payments.union.build",
});
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("1. Depositing on source chain...");
const
const depositRequests: readonly [{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}, ...{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]]
depositRequests
= await
import Payment
Payment
.
const prepareDeposit: (options: {
sourceWalletClient: WalletClient;
} & Parameters<typeof prepareDeposit>[0]) => Promise<readonly [{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}, ...{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]]>
prepareDeposit
({
DepositOptions.destinationChainId: string & Brand<"UniversalChainId">
destinationChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
DepositOptions.depositAddress: DepositAddress
depositAddress
,
DepositOptions.amount: bigint

Amount to deposit (in underlying token's smallest unit)

amount
: 1n,
sourceWalletClient: WalletClient
sourceWalletClient
:
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
,
DepositOptions.srcErc20Address: Domain.Erc20Address
srcErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
});
const
const signedRequests: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}[]
signedRequests
= await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.sign: (request: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
} | readonly {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]) => Promise<...>
sign
(
const depositRequests: readonly [{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}, ...{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]]
depositRequests
);
const
const submissions: Viem.TransactionReceipt[]
submissions
:
interface Array<T>
Array
<
import Viem
Viem
.
type TransactionReceipt<quantity = bigint, index = number, status = "success" | "reverted", type = TransactionType> = {
blobGasPrice?: quantity | undefined;
blobGasUsed?: quantity | undefined;
blockHash: Viem.Hash;
blockNumber: quantity;
contractAddress: Viem.Address | null | undefined;
cumulativeGasUsed: quantity;
effectiveGasPrice: quantity;
from: Viem.Address;
gasUsed: quantity;
logs: Viem.Log<quantity, index, false>[];
logsBloom: Viem.Hex;
root?: Viem.Hash | undefined;
status: status;
to: Viem.Address | null;
transactionHash: Viem.Hash;
transactionIndex: index;
type: type;
}
export TransactionReceipt
TransactionReceipt
> = [];
for (const
const signed: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signed
of
const signedRequests: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}[]
signedRequests
)
const submissions: Viem.TransactionReceipt[]
submissions
.
Array<TransactionReceipt>.push(...items: Viem.TransactionReceipt[]): number

Appends new elements to the end of an array, and returns the new length of the array.

@paramitems New elements to add to the array.

push
(
await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.submit: (request: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}) => Promise<{
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}>
submit
(
const signed: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signed
)
.
Promise<{ readonly _tag: "SubmissionEvm"; readonly hash: TxHash; }>.then<Viem.TransactionReceipt, Viem.TransactionReceipt>(onfulfilled?: ((value: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}) => Viem.TransactionReceipt | PromiseLike<Viem.TransactionReceipt>) | null | undefined, onrejected?: ((reason: any) => Viem.TransactionReceipt | PromiseLike<Viem.TransactionReceipt>) | null | undefined): Promise<Viem.TransactionReceipt>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(({
hash: Domain.TxHash
hash
}) =>
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
.
EvmPublicClient.waitForTransactionReceipt: (hash: Domain.TxHash) => Promise<Viem.TransactionReceipt>
waitForTransactionReceipt
(
hash: Domain.TxHash
hash
)),
);
await
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
.
PublicClient.waitForBlock: (targetHeight: bigint) => Promise<bigint>
waitForBlock
(
const submissions: Viem.TransactionReceipt[]
submissions
.
Array<TransactionReceipt>.at(index: number): Viem.TransactionReceipt | undefined

Returns the item located at the specified index.

@paramindex The zero-based index of the desired code unit. A negative index will count back from the last item.

at
(-1)!.
blockNumber: bigint

Number of block containing this transaction

blockNumber
);
const
const txLabels: string[]
txLabels
= ["Approval", "Deposit", "Transfer"];
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("Transaction links:");
for (let
let i: number
i
= 0;
let i: number
i
<
const submissions: Viem.TransactionReceipt[]
submissions
.
Array<T>.length: number

Gets or sets the length of the array. This is a number one higher than the highest index in the array.

length
;
let i: number
i
++) {
const
const receipt: Viem.TransactionReceipt
receipt
=
const submissions: Viem.TransactionReceipt[]
submissions
[
let i: number
i
];
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
` ${
const txLabels: string[]
txLabels
[
let i: number
i
]}: https://basescan.org/tx/${
const receipt: Viem.TransactionReceipt
receipt
.
transactionHash: `0x${string}`

Hash of this transaction

transactionHash
}`,
);
}
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("2. Updating light client...");
const
const updateRequest: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}
updateRequest
= await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.updateLoopbackClient: (args: WalletClient.UpdateLoopbackClient) => Promise<{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}>
updateLoopbackClient
({
WalletClient.UpdateLoopbackClient.clientId: number
clientId
: 5,
WalletClient.UpdateLoopbackClient.height: bigint
height
:
const submissions: Viem.TransactionReceipt[]
submissions
[2].
blockNumber: bigint

Number of block containing this transaction

blockNumber
,
WalletClient.UpdateLoopbackClient.ibcHandlerAddress: Domain.IbcCoreAddress
ibcHandlerAddress
:
import IbcCoreRegistry
IbcCoreRegistry
.
const getIbcCoreAddressOrThrow: (ucid: string & Brand<"UniversalChainId">) => Domain.IbcCoreAddress
getIbcCoreAddressOrThrow
(
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
),
WalletClient.UpdateLoopbackClient.universalChainId: string & Brand<"UniversalChainId">
universalChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
});
const [
const signedRequest: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signedRequest
] = await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.sign: (request: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
} | readonly {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]) => Promise<...>
sign
(
const updateRequest: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}
updateRequest
);
const
const result: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}
result
= await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.submit: (request: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}) => Promise<{
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}>
submit
(
const signedRequest: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signedRequest
);
const
const lcUpdateReceipt: Viem.TransactionReceipt
lcUpdateReceipt
= await
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
.
EvmPublicClient.waitForTransactionReceipt: (hash: Domain.TxHash) => Promise<Viem.TransactionReceipt>
waitForTransactionReceipt
(
const result: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}
result
.
hash: Domain.TxHash
hash
,
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(` Update: https://basescan.org/tx/${
const result: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}
result
.
hash: Domain.TxHash
hash
}`);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("3. Checking balance...");
await
const sleep: (ms: number) => Promise<unknown>
sleep
(20_000);
const
const balance: PublicClient.BalanceInfo
balance
= await
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
.
PublicClient.readBalance: (options: PublicClient.ReadBalanceOptions) => Promise<PublicClient.BalanceInfo>
readBalance
({
PublicClient.ReadBalanceOptions.srcErc20Address: Domain.Erc20Address
srcErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
PublicClient.ReadBalanceOptions.dstErc20Address: Domain.Erc20Address
dstErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
PublicClient.ReadBalanceOptions.srcChainId: string & Brand<"UniversalChainId">
srcChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
PublicClient.ReadBalanceOptions.dstChainId: string & Brand<"UniversalChainId">
dstChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
PublicClient.ReadBalanceOptions.depositAddress: `0x${string}`
depositAddress
:
const depositAddress: {
beneficiaries: [Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address];
zAssetAddress: Domain.ZAssetAddress;
destinationChainId: string & Brand<"UniversalChainId">;
}
depositAddress
.
zAssetAddress: Domain.ZAssetAddress
zAssetAddress
,
PublicClient.ReadBalanceOptions.nullifier: Domain.Nullifier
nullifier
,
PublicClient.ReadBalanceOptions.clientId: number
clientId
: 5,
});
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
({
balance: PublicClient.BalanceInfo
balance
});
// Wait 4 extra seconds for Load Balancers
await
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
.
PublicClient.waitForBlock: (targetHeight: bigint) => Promise<bigint>
waitForBlock
(
const lcUpdateReceipt: Viem.TransactionReceipt
lcUpdateReceipt
.
blockNumber: bigint

Number of block containing this transaction

blockNumber
+ 4n);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("4. Redeeming on destination");
const
const proof: Proof
proof
= await
import Payment
Payment
.
const generateProof: (options: {
destinationPublicClient: PublicClient;
sourcePublicClient: PublicClient;
publicClient: PublicClient;
prover: Prover.Prover;
} & Parameters<typeof generateProof>[0]) => Promise<Proof>
generateProof
({
paymentKey: Domain.PaymentKey
paymentKey
,
depositAddress: DepositAddress
depositAddress
,
nullifier: Domain.Nullifier
nullifier
,
beneficiary: Domain.Erc20Address
beneficiary
:
const BENEFICIARY: Domain.Erc20Address
BENEFICIARY
,
amount: bigint
amount
: 1n,
clientIds: number[]
clientIds
: [5],
selectedClientId: number
selectedClientId
: 5,
srcChainId: string & Brand<"UniversalChainId">
srcChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
srcErc20Address: Domain.Erc20Address
srcErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
dstErc20Address: Domain.Erc20Address
dstErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
publicClient: PublicClient
publicClient
,
sourcePublicClient: PublicClient
sourcePublicClient
:
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
,
destinationPublicClient: PublicClient
destinationPublicClient
:
const publicClient: EvmPublicClient.EvmPublicClient
publicClient
,
prover: Prover.Prover
prover
,
});
const
const attestation: {
readonly id: string;
readonly hash: `0x${string}`;
readonly signature: `0x${string}`;
readonly attestedMessage: `0x${string}`;
readonly signerAddress: `0x${string}`;
}
attestation
= await
const attestor: Attestor.Attestor
attestor
.
Attestor.get: (payload: {
unspendableAddress: Address;
beneficiary: Address;
}) => Promise<{
readonly id: string;
readonly hash: `0x${string}`;
readonly signature: `0x${string}`;
readonly attestedMessage: `0x${string}`;
readonly signerAddress: `0x${string}`;
}>
get
({
unspendableAddress: `0x${string}`
unspendableAddress
:
const depositAddress: {
beneficiaries: [Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address, Domain.Erc20Address];
zAssetAddress: Domain.ZAssetAddress;
destinationChainId: string & Brand<"UniversalChainId">;
}
depositAddress
.
zAssetAddress: Domain.ZAssetAddress
zAssetAddress
,
beneficiary: `0x${string}`
beneficiary
:
const BENEFICIARY: Domain.Erc20Address
BENEFICIARY
,
});
const
const redemptionRequest: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}
redemptionRequest
= await
import Payment
Payment
.
const prepareRedemption: (options: {
destinationWalletClient: WalletClient;
} & Parameters<typeof prepareRedemption>[0]) => Promise<{
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}>
prepareRedemption
({
proof: Proof
proof
,
dstErc20Address: Domain.Erc20Address
dstErc20Address
:
const ASSET_ADDRESS: Domain.Erc20Address
ASSET_ADDRESS
,
attestation: {
readonly id: string;
readonly hash: `0x${string}`;
readonly signature: `0x${string}`;
readonly attestedMessage: `0x${string}`;
readonly signerAddress: `0x${string}`;
}
attestation
,
destinationWalletClient: WalletClient
destinationWalletClient
:
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
,
// @annotate: for the destination
universalChainId: string & Brand<"UniversalChainId">
universalChainId
:
const BASE_UNIVERSAL_CHAIN_ID: string & Brand<"UniversalChainId">
BASE_UNIVERSAL_CHAIN_ID
,
});
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
({
redemptionRequest: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}
redemptionRequest
});
const [
const signedRedemption: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signedRedemption
] = await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.sign: (request: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
} | readonly {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}[]) => Promise<...>
sign
(
const redemptionRequest: {
readonly _tag: "PreparedEvm";
readonly kind: "Erc20.Approve" | "Erc20.Wrap" | "ZAsset.Transfer" | "LoopbackClient.Update";
readonly universalChainId: Domain.UniversalChainId;
readonly contractAddress: Domain.Erc20Address;
readonly abi: Viem.Abi;
readonly functionName: string;
readonly args: ReadonlyArray<unknown>;
}
redemptionRequest
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
({
signedRedemption: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signedRedemption
});
const
const submittedRedemption: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}
submittedRedemption
= await
const walletClient: EvmWalletClient.EvmWalletClient
walletClient
.
WalletClient.submit: (request: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}) => Promise<{
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}>
submit
(
const signedRedemption: {
readonly _tag: "SignedEvm";
readonly value: Viem.SignTransactionReturnType;
}
signedRedemption
);
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
({
submittedRedemption: {
readonly _tag: "SubmissionEvm";
readonly hash: Domain.TxHash;
}
submittedRedemption
});
return "DONE";
}
function main(): Promise<string>
main
().
Promise<string>.then<void, never>(onfulfilled?: ((value: string) => void | PromiseLike<void>) | null | undefined, onrejected?: ((reason: any) => PromiseLike<never>) | null | undefined): Promise<void>

Attaches callbacks for the resolution and/or rejection of the Promise.

@paramonfulfilled The callback to execute when the Promise is resolved.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of which ever callback is executed.

then
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(...data: any[]): void (+1 overload)

The console.log() static method outputs a message to the console.

MDN Reference

log
).
Promise<void>.catch<void>(onrejected?: ((reason: any) => void | PromiseLike<void>) | null | undefined): Promise<void>

Attaches a callback for only the rejection of the Promise.

@paramonrejected The callback to execute when the Promise is rejected.

@returnsA Promise for the completion of the callback.

catch
(
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.error(...data: any[]): void (+1 overload)

The console.error() static method outputs a message to the console at the 'error' log level.

MDN Reference

error
);

Explore various usecases for Union Private Payments.