Skip to content

wormhole-foundation/demo-ntt-evm-multisig-tools

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NTT EVM Safe Multisig Tools

Scripts that generate Safe Transaction Builder JSON files for managing Wormhole NTT (Native Token Transfers) deployments from a Safe multisig.

No private keys required - the scripts generate JSON files that signers import into the Safe UI and sign with their own wallets.

Uses the Wormhole ts-sdk for calldata generation, ensuring ABI compatibility across NTT versions.

How It Works

  1. Copy an example config and fill in your contract addresses and parameters
  2. Run the script to generate a Safe Transaction Builder JSON file
  3. Import the JSON into the Safe Transaction Builder (see Importing into Safe)
  4. Safe owners review the decoded transactions, sign, and execute

Setup

git clone https://github.com/wormhole-foundation/demo-ntt-evm-multisig-tools.git
cd demo-ntt-evm-multisig-tools
npm install

Available Scripts

Command Description
npm run extend-to-evm-chain Register NTT peers between two EVM chains (bidirectional)
npm run extend-to-svm-chain Register a Solana/SVM chain as NTT peer on an EVM chain
npm run set-rate-limits Update outbound and/or inbound rate limits
npm run pause Pause or unpause the NTT Manager
npm run transfer-ownership Transfer NTT Manager ownership to a new address

Importing into Safe

All scripts output JSON files to the output/ directory. To execute them:

  1. Open your Safe at app.safe.global
  2. Make sure you are connected to the correct network (e.g., Sepolia, Base, Ethereum Mainnet)
  3. Click New Transaction in the left sidebar
  4. Select Transaction Builder
  5. Drag and drop the generated JSON file (or click the upload area to browse)
  6. The Transaction Builder will decode and display each transaction with its function name and parameters - review them carefully
  7. Click Create Batch then Send Batch
  8. Other Safe owners will see the pending transaction in the Safe UI and can confirm it
  9. Once the signature threshold is met, any owner can execute the transaction on-chain

Config Fields

All configs require the following common fields:

Field Description
network "Mainnet" or "Testnet"
rpcUrl RPC endpoint for the EVM chain
wormholeChain Wormhole ts-sdk chain name (e.g., "Sepolia", "BaseSepolia", "Ethereum", "Base", "Arbitrum")
evmChainId The EVM chain ID (e.g., "11155111" for Sepolia)
safeAddress Your Safe multisig address
nttManager The NTT Manager proxy contract address
wormholeTransceiver The Wormhole Transceiver proxy contract address

See the example configs in src/config/ for the full structure of each script.

Scripts

Extend NTT to a New EVM Chain

Generates Safe transaction batches for registering NTT peers between two chains. Two JSON files are generated - one for each chain - so both sides can be configured via their respective Safe multisigs.

Each batch contains:

  1. NttManager.setPeer - Register the remote chain's NTT Manager and set the inbound rate limit
  2. WormholeTransceiver.setWormholePeer - Register the remote chain's Wormhole transceiver

Note: setWormholePeer is a one-shot call - it reverts if a peer is already registered for that chain ID. To change a peer, you must deploy a new transceiver.

cp src/config/extendToEvmChain.example.json src/config/extendToEvmChain.json
# Edit src/config/extendToEvmChain.json with your values
npm run extend-to-evm-chain

Extend NTT to a Solana/SVM Chain

Generates a Safe transaction batch for registering an SVM-based NTT deployment (Solana, Fogo, etc.) as a peer on an EVM chain. Only one JSON file is generated (EVM side) - the SVM side should be configured using the Solana multisig tools.

Each batch contains:

  1. NttManager.setPeer - Register the SVM NTT Manager and set the inbound rate limit
  2. WormholeTransceiver.setWormholePeer - Register the SVM Wormhole transceiver
cp src/config/extendToSvmChain.example.json src/config/extendToSvmChain.json
# Edit src/config/extendToSvmChain.json with your values
npm run extend-to-svm-chain

Set Rate Limits

Update outbound and/or per-chain inbound rate limits on the NTT Manager.

For inbound limits, chainName must be a canonical Wormhole ts-sdk chain name.

cp src/config/setRateLimits.example.json src/config/setRateLimits.json
# Edit src/config/setRateLimits.json with your values
npm run set-rate-limits

Pause / Unpause

Pause or unpause the NTT Manager. When paused, no transfers can be initiated or completed.

cp src/config/pause.example.json src/config/pause.json
# Edit src/config/pause.json - set "action" to "pause" or "unpause"
npm run pause

Note: Only the owner can unpause. Both the owner and the designated pauser can pause.

Transfer Ownership

Transfer ownership of the NTT Manager (and all registered transceivers) to a new address.

cp src/config/transferOwnership.example.json src/config/transferOwnership.json
# Edit src/config/transferOwnership.json with the new owner address
npm run transfer-ownership

Warning: This transfers ownership of the NTT Manager AND all registered transceivers. Double-check the newOwner address before executing.

Project Structure

src/
├── __tests__/                       # Unit tests
│   ├── encoding.test.ts
│   └── safeBatchBuilder.test.ts
├── config/
│   ├── extendToEvmChain.example.json
│   ├── extendToSvmChain.example.json
│   ├── setRateLimits.example.json
│   ├── pause.example.json
│   └── transferOwnership.example.json
├── scripts/
│   ├── extendToEvmChain.ts       # Register peers between two EVM chains
│   ├── extendToSvmChain.ts         # Register SVM chain as peer on EVM chain
│   ├── setRateLimits.ts             # Update rate limits
│   ├── pause.ts                     # Pause or unpause NTT
│   └── transferOwnership.ts         # Transfer NTT ownership
└── utils/
    ├── encoding.ts                  # Input validation and string helpers
    ├── nttClient.ts                 # Wormhole SDK wrapper for calldata generation
    └── safeBatchBuilder.ts          # Safe Transaction Builder JSON generator
output/                              # Generated JSON files (gitignored)

Security

  • No private keys are used or required by these scripts
  • All signing happens in the Safe UI via connected wallets (MetaMask, Ledger, etc.)
  • Config files with real addresses are gitignored - only example configs are committed
  • Safety-critical config fields are validated before encoding - invalid addresses, RPC URLs, network names, chain IDs, decimals, and limits will produce clear error messages
  • Always review the decoded transaction details in the Safe Transaction Builder before signing

About

Safe multisig transaction tools for Wormhole NTT management on EVM chains

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages