Wormhole CLI
This tool is a command-line interface to Wormhole, allowing you to perform various actions, such as querying a transaction's status or submitting token transfers.
Installation
Clone the repository and change directories to the appropriate directory:
Build and install the CLI tool:
This installs two binaries, worm-fetch-governance
and worm
on your $PATH
. To use worm
, set up $HOME/.wormhole/.env
with your private keys, based on .env.sample
in this folder.
Usage
You can interact with the Wormhole CLI by typing worm
and including the command
and any necessary subcommands and parameters.
Command | Description |
---|---|
worm aptos INSERT_COMMAND |
Aptos utilities |
worm edit-vaa INSERT_COMMAND |
Edits or generates a VAA |
worm evm INSERT_COMMAND |
EVM utilities |
worm generate INSERT_COMMAND |
Generate VAAs (DevNet and Testnet only) |
worm info INSERT_COMMAND |
Contract, chain, RPC, and address information utilities |
worm near INSERT_NETWORK, INSERT_ACCOUNT |
NEAR utilities |
worm parse INSERT_VAA |
Parse a VAA (can be in either hex or base64 format) |
worm recover INSERT_DIGEST INSERT_SIGNATURE |
Recover an address from a signature |
worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH |
Prints information about the automatic delivery initiated on the specified network, chain, and transaction hash |
worm submit INSERT_VAA |
Execute a VAA |
worm sui INSERT_COMMAND |
Sui utilities |
worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK |
Transfers a token |
worm verify-vaa INSERT_VAA, INSERT_NETWORK |
Verifies a VAA by querying the Core Contract on Ethereum |
You can also refer to the below options, available with all worm
commands:
Subcommands
Aptos
worm aptos INSERT_COMMAND
Commands:
worm aptos init-token-bridge Init token bridge contract
worm aptos init-wormhole Init Wormhole core contract
worm aptos deploy <package-dir> Deploy an Aptos package
worm aptos deploy-resource <seed> Deploy an Aptos package using a
<package-dir> resource account
worm aptos send-example-message Send example message
<message>
worm aptos derive-resource-account Derive resource account address
<account> <seed>
worm aptos derive-wrapped-address Derive wrapped coin type
<chain> <origin-address>
worm aptos hash-contracts <package-dir> Hash contract bytecodes for upgrade
worm aptos upgrade <package-dir> Perform upgrade after VAA has been
submitted
worm aptos migrate Perform migration after contract
upgrade
worm aptos faucet Request money from the faucet for a
given account
worm aptos start-validator Start a local aptos validator
Options:
--help Show help [boolean]
--version Show version number [boolean]
Edit VAA
worm edit-vaa INSERT_COMMAND
Options:
--help Show help [boolean]
--version Show version number [boolean]
-v, --vaa vaa in hex format [string] [required]
-n, --network Network
[required] [choices: "mainnet", "testnet", "devnet"]
--guardian-set-index, --gsi guardian set index [number]
--signatures, --sigs comma separated list of signatures [string]
--wormscanurl, --wsu url to wormscan entry for the vaa that
includes signatures [string]
--wormscan, --ws if specified, will query the wormscan entry
for the vaa to get the signatures [boolean]
--emitter-chain-id, --ec emitter chain id to be used in the vaa
[number]
--emitter-address, --ea emitter address to be used in the vaa[string]
--nonce, --no nonce to be used in the vaa [number]
--sequence, --seq sequence number to be used in the vaa[string]
--consistency-level, --cl consistency level to be used in the vaa
[number]
--timestamp, --ts timestamp to be used in the vaa in unix
seconds [number]
-p, --payload payload in hex format [string]
--guardian-secret, --gs Guardian's secret key [string]
EVM
worm evm INSERT_COMMAND
Commands:
worm evm address-from-secret <secret> Compute a 20 byte eth address from a 32
byte private key
worm evm storage-update Update a storage slot on an EVM fork
during testing (anvil or hardhat)
worm evm chains Return all EVM chains
worm evm info Query info about the on-chain state of
the contract
worm evm hijack Override the guardian set of the core
bridge contract during testing (anvil
or hardhat)
worm evm start-validator Start a local EVM validator
Options:
--help Show help [boolean]
--version Show version number [boolean]
--rpc RPC endpoint [string]
Generate
worm generate INSERT_COMMAND
Commands:
worm generate registration Generate registration VAA
worm generate upgrade Generate contract upgrade VAA
worm generate attestation Generate a token attestation VAA
worm generate recover-chain-id Generate a recover chain ID VAA
worm generate Sets the default delivery provider
set-default-delivery-provider for the Wormhole Relayer contract
Options:
--help Show help [boolean]
--version Show version number [boolean]
-g, --guardian-secret Guardians' secret keys (CSV) [string] [required]
Info
worm info INSERT_COMMAND
Commands:
worm info chain-id <chain> Print the wormhole chain ID integer
associated with the specified chain
name
worm info contract <network> <chain> Print contract address
<module>
worm info emitter <chain> <address> Print address in emitter address
format
worm info origin <chain> <address> Print the origin chain and address
of the asset that corresponds to the
given chain and address.
worm info registrations <network> Print chain registrations
<chain> <module>
worm info rpc <network> <chain> Print RPC address
worm info wrapped <origin-chain> Print the wrapped address on the
<origin-address> <target-chain> target chain that corresponds with
the specified origin chain and
address.
Options:
--help Show help [boolean]
--version Show version number [boolean]
NEAR
worm near INSERT_COMMAND
Commands:
worm near contract-update <file> Submit a contract update using our specific
APIs
worm near deploy <file> Submit a contract update using near APIs
Options:
--help Show help [boolean]
--version Show version number [boolean]
-m, --module Module to query [choices: "Core", "NFTBridge", "TokenBridge"]
-n, --network Network [required] [choices: "mainnet", "testnet", "devnet"]
--account Near deployment account [string] [required]
--attach Attach some near [string]
--target Near account to upgrade [string]
--mnemonic Near private keys [string]
--key Near private key [string]
-r, --rpc Override default rpc endpoint url [string]
Parse
Recover
Status
worm status INSERT_NETWORK, INSERT_CHAIN, INSERT_TXN_HASH
Positionals:
network Network [choices:
'mainnet',
'testnet',
'devnet']
chain Source chain
[choices:
'unset',
'solana',
'ethereum',
'terra',
'bsc',
'polygon',
'avalanche',
'oasis',
'algorand',
'aurora',
'fantom',
'karura',
'acala',
'klaytn',
'celo',
'near',
'moonbeam',
'neon',
'terra2',
'injective',
'osmosis',
'sui',
'aptos',
'arbitrum',
'optimism',
'gnosis',
'pythnet',
'xpla',
'btc',
'base',
'sei',
'rootstock',
'scroll',
'mantle',
'blast',
'xlayer',
'linea',
'berachain',
'seievm',
'wormchain',
'cosmoshub',
'evmos',
'kujira',
'neutron',
'celestia',
'stargaze',
'seda',
'dymension',
'provenance',
'sepolia',
'arbitrum_sepolia',
'base_sepolia',
'optimism_sepolia',
'holesky',
'polygon_sepolia']
tx Source transaction hash [string]
Options:
--help Show help [boolean]
--version Show version number [boolean]
Submit
worm submit INSERT_VAA
Positionals:
vaa vaa [string]
Options:
--help Show help [boolean]
--version Show version number [boolean]
-c, --chain chain name
[choices: 'unset',
'solana',
'ethereum',
'terra',
'bsc',
'polygon',
'avalanche',
'oasis',
'algorand',
'aurora',
'fantom',
'karura',
'acala',
'klaytn',
'celo',
'near',
'moonbeam',
'neon',
'terra2',
'injective',
'osmosis',
'sui',
'aptos',
'arbitrum',
'optimism',
'gnosis',
'pythnet',
'xpla',
'btc',
'base',
'sei',
'rootstock',
'scroll',
'mantle',
'blast',
'xlayer',
'linea',
'berachain',
'seievm',
'wormchain',
'cosmoshub',
'evmos',
'kujira',
'neutron',
'celestia',
'stargaze',
'seda',
'dymension',
'provenance',
'sepolia',
'arbitrum_sepolia',
'base_sepolia',
'optimism_sepolia',
'holesky',
'polygon_sepolia']
-n, --network Network
[required]
[choices:
'mainnet',
'testnet',
'devnet']
-a, --contract-address Contract to submit VAA to (override config) [string]
--rpc RPC endpoint [string]
--all-chains, --ac Submit the VAA to all chains except for the origin
chain specified in the payload
[boolean] [default: false]
Sui
worm sui INSERT_COMMAND
Commands:
worm sui build-coin Build wrapped coin and dump bytecode.
Example:
worm sui build-coin -d 8 -v V__0_1_1 -n
testnet -r
"https://fullnode.testnet.sui.io:443"
worm sui deploy <package-dir> Deploy a Sui package
worm sui init-example-message-app Initialize example core message app
worm sui init-token-bridge Initialize token bridge contract
worm sui init-wormhole Initialize wormhole core contract
worm sui publish-example-message Publish message from example app via
core bridge
worm sui setup-devnet Setup devnet by deploying and
initializing core and token bridges and
submitting chain registrations.
worm sui objects <owner> Get owned objects by owner
worm sui package-id <state-object-id> Get package ID from State object ID
worm sui tx <transaction-digest> Get transaction details
Options:
--help Show help [boolean]
--version Show version number [boolean]
Transfer
worm transfer INSERT_SOURCE_CHAIN, INSERT_DESTINATION_CHAIN, INSERT_DESTINATION_ADDRESS, INSERT_AMOUNT, INSERT_NETWORK
Options:
--help Show help [boolean]
--version Show version number [boolean]
--src-chain source chain [required] [choices:
'solana',
'ethereum',
'terra',
'bsc',
'polygon',
'avalanche',
'oasis',
'algorand',
'aurora',
'fantom',
'karura',
'acala',
'klaytn',
'celo',
'near',
'moonbeam',
'neon',
'terra2',
'injective',
'osmosis',
'sui',
'aptos',
'arbitrum',
'optimism',
'gnosis',
'pythnet',
'xpla',
'btc',
'base',
'sei',
'rootstock',
'scroll',
'mantle',
'blast',
'xlayer',
'linea',
'berachain',
'seievm',
'wormchain',
'cosmoshub',
'evmos',
'kujira',
'neutron',
'celestia',
'stargaze',
'seda',
'dymension',
'provenance',
'sepolia',
'arbitrum_sepolia',
'base_sepolia',
'optimism_sepolia',
'holesky',
'polygon_sepolia']
--dst-chain destination chain
[required] [choices:
'solana',
'ethereum',
'terra',
'bsc',
'polygon',
'avalanche',
'oasis',
'algorand',
'aurora',
'fantom',
'karura',
'acala',
'klaytn',
'celo',
'near',
'moonbeam',
'neon',
'terra2',
'injective',
'osmosis',
'sui',
'aptos',
'arbitrum',
'optimism',
'gnosis',
'pythnet',
'xpla',
'btc',
'base',
'sei',
'rootstock',
'scroll',
'mantle',
'blast',
'xlayer',
'linea',
'berachain',
'seievm',
'wormchain',
'cosmoshub',
'evmos',
'kujira',
'neutron',
'celestia',
'stargaze',
'seda',
'dymension',
'provenance',
'sepolia',
'arbitrum_sepolia',
'base_sepolia',
'optimism_sepolia',
'holesky',
'polygon_sepolia']
--dst-addr destination address [string] [required]
--token-addr token address [string] [default: native token]
--amount token amount [string] [required]
-n, --network Network [required] [choices: "mainnet", "testnet", "devnet"]
--rpc RPC endpoint [string]
Verify VAA
Examples
VAA generation
Use generate
to create VAAs for testing. For example, use the following command to create an NFT bridge registration VAA:
worm generate registration --module NFTBridge \
--chain bsc \
--contract-address 0x706abc4E45D419950511e474C7B9Ed348A4a716c \
--guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0
The below example generates a token attestation VAA:
worm generate attestation --emitter-chain ethereum \
--emitter-address 11111111111111111111111111111115 \
--chain ethereum \
--token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
--decimals 6 \
--symbol USDC \
--name USDC \
--guardian-secret cfb12303a19cde580bb4dd771639b0d26bc68353645571a8cff516ab2ee113a0
VAA parsing
Use parse
to parse a VAA into JSON:
This example will fetch governance VAA 13940208096455381020
and print it as JSON:
# ...signatures elided
timestamp: 1651416474,
nonce: 1570649151,
emitterChain: 1,
emitterAddress: '0000000000000000000000000000000000000000000000000000000000000004',
sequence: 13940208096455381020n,
consistencyLevel: 32,
payload: {
module: 'Core',
type: 'GuardianSetUpgrade',
chain: 0,
newGuardianSetIndex: 2,
newGuardianSetLength: 19,
newGuardianSet: [
'58cc3ae5c097b213ce3c81979e1b9f9570746aa5',
'ff6cb952589bde862c25ef4392132fb9d4a42157',
'114de8460193bdf3a2fcf81f86a09765f4762fd1',
'107a0086b32d7a0977926a205131d8731d39cbeb',
'8c82b2fd82faed2711d59af0f2499d16e726f6b2',
'11b39756c042441be6d8650b69b54ebe715e2343',
'54ce5b4d348fb74b958e8966e2ec3dbd4958a7cd',
'66b9590e1c41e0b226937bf9217d1d67fd4e91f5',
'74a3bf913953d695260d88bc1aa25a4eee363ef0',
'000ac0076727b35fbea2dac28fee5ccb0fea768e',
'af45ced136b9d9e24903464ae889f5c8a723fc14',
'f93124b7c738843cbb89e864c862c38cddcccf95',
'd2cc37a4dc036a8d232b48f62cdd4731412f4890',
'da798f6896a3331f64b48c12d1d57fd9cbe70811',
'71aa1be1d36cafe3867910f99c09e347899c19c3',
'8192b6e7387ccd768277c17dab1b7a5027c0b3cf',
'178e21ad2e77ae06711549cfbb1f9c7a9d8096e8',
'5e1487f35515d02a92753504a8d75471b9f49edb',
'6fbebc898f403e4773e95feb15e80c9a99c8348d'
]
}
Submitting VAAs
Use submit
to submit a VAA to a chain. It first parses the VAA and determines the destination chain and module. For example, a contract upgrade contains both the target chain and module, so the only required argument is the network moniker (mainnet
or testnet
):
The script will ask you to specify the target chain for VAAs that don't have a specific target chain (like registrations or Guardian set upgrades). For example, to submit a Guardian set upgrade on all chains, simply run:
worm-fetch-governance 13940208096455381020 > guardian-upgrade.txt
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain oasis
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain aurora
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain fantom
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain karura
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain acala
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain klaytn
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain avalanche
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain polygon
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain bsc
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain solana
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain terra
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain ethereum
worm submit $(cat guardian-upgrade.txt) --network mainnet --chain celo
The VAA payload type (Guardian set upgrade) specifies that this VAA should go to the core bridge, and the tool directs it there.
Getting Info
To get info about a contract (only EVM supported at this time), use the following command:
Running this command generates the following output:
{
"address": "0xB6F6D86a8f9879A9c87f643768d9efc38c1Da6E7",
"wormhole": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B",
"implementation": "0x621199f6beB2ba6fbD962E8A52A320EA4F6D4aA3",
"isInitialized": true,
"tokenImplementation": "0x7f8C5e730121657E17E452c5a1bA3fA1eF96f22a",
"chainId": 4,
"finality": 15,
"evmChainId": "56",
"isFork": false,
"governanceChainId": 1,
"governanceContract": "0x0000000000000000000000000000000000000000000000000000000000000004",
"WETH": "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
"registrations": {
"Solana": "0xec7372995d5cc8732397fb0ad35c0121e0eaa90d26f828a534cab54391b3a4f5",
"Ethereum": "0x0000000000000000000000003ee18b2214aff97000d974cf647e7c347e8fa585",
"Terra": "0x0000000000000000000000007cf7b764e38a0a5e967972c1df77d432510564e2",
"Polygon": "0x0000000000000000000000005a58505a96d1dbf8df91cb21b54419fc36e93fde",
"Avalanche": "0x0000000000000000000000000e082f06ff657d94310cb8ce8b0d9a04541d8052",
"Oasis": "0x0000000000000000000000005848c791e09901b40a9ef749f2a6735b418d7564",
"Algorand": "0x67e93fa6c8ac5c819990aa7340c0c16b508abb1178be9b30d024b8ac25193d45",
"Aurora": "0x00000000000000000000000051b5123a7b0f9b2ba265f9c4c8de7d78d52f510f",
"Fantom": "0x0000000000000000000000007c9fc5741288cdfdd83ceb07f3ea7e22618d79d2",
"Karura": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624",
"Acala": "0x000000000000000000000000ae9d7fe007b3327aa64a32824aaac52c42a6e624",
"Klaytn": "0x0000000000000000000000005b08ac39eaed75c0439fc750d9fe7e1f9dd0193f",
"Celo": "0x000000000000000000000000796dff6d74f3e27060b71255fe517bfb23c93eed",
"Near": "0x148410499d3fcda4dcfd68a1ebfcdddda16ab28326448d4aae4d2f0465cdfcb7",
"Moonbeam": "0x000000000000000000000000b1731c586ca89a23809861c6103f0b96b3f57d92",
"Neon": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Terra2": "0xa463ad028fb79679cfc8ce1efba35ac0e77b35080a1abe9bebe83461f176b0a3",
"Injective": "0x00000000000000000000000045dbea4617971d93188eda21530bc6503d153313",
"Osmosis": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Sui": "0xccceeb29348f71bdd22ffef43a2a19c1f5b5e17c5cca5411529120182672ade5",
"Aptos": "0x0000000000000000000000000000000000000000000000000000000000000001",
"Arbitrum": "0x0000000000000000000000000b2402144bb366a632d14b83f244d2e0e21bd39c",
"Optimism": "0x0000000000000000000000001d68124e65fafc907325e3edbf8c4d84499daa8b",
"Gnosis": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Pythnet": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Xpla": "0x8f9cf727175353b17a5f574270e370776123d90fd74956ae4277962b4fdee24c",
"Btc": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Base": "0x0000000000000000000000008d2de8d2f73f1f4cab472ac9a881c9b123c79627",
"Sei": "0x86c5fd957e2db8389553e1728f9c27964b22a8154091ccba54d75f4b10c61f5e",
"Rootstock": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Scroll": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d",
"Mantle": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d",
"Blast": "0x00000000000000000000000024850c6f61c438823f01b7a3bf2b89b72174fa9d",
"Xlayer": "0x0000000000000000000000005537857664b0f9efe38c9f320f75fef23234d904",
"Linea": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Berachain": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Seievm": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Snaxchain": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Wormchain": "0xaeb534c45c3049d380b9d9b966f9895f53abd4301bfaff407fa09dea8ae7a924",
"Cosmoshub": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Evmos": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Kujira": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Neutron": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Celestia": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Stargaze": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Seda": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Dymension": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Provenance": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Sepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
"ArbitrumSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
"BaseSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
"OptimismSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000",
"Holesky": "0x0000000000000000000000000000000000000000000000000000000000000000",
"PolygonSepolia": "0x0000000000000000000000000000000000000000000000000000000000000000"
}
}
Additional Info Examples
You can get the contract address for a module as follows:
To get the contract address for NFTBridge
on BSC Mainnet, for example, you can provide the following command:
You can get the RPC address for a chain as follows:
To get the RPC address for BSC Mainnet, for example, you can provide the following command: