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: