Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
784b473
solana: add governance SDK module for VAA execution
evgeniko Mar 27, 2026
d458340
solana: add governance scripts infrastructure (env, helpers, config)
evgeniko Mar 27, 2026
2ce452e
solana: add executeGovernanceVaa scripts (ledger single, ledger batch…
evgeniko Mar 27, 2026
b2856fc
solana: add governance ownership transfer and diagnostic scripts
evgeniko Mar 27, 2026
4fd8134
evm: add ts-scripts package scaffolding and config
evgeniko Mar 27, 2026
f3a5109
evm: add ts-scripts environment and config loading
evgeniko Mar 27, 2026
074bd5b
evm: add governance scripts (execute VAA, create message)
evgeniko Mar 27, 2026
21930b6
evm: add transceiver config reading script
evgeniko Mar 27, 2026
3f4eac9
docs: add deployment documentation and governance shell script
evgeniko Mar 27, 2026
ca2d12a
fix: restore mainnet RPC URL, fix trailing newlines, update lockfile
evgeniko Mar 27, 2026
9e273fc
fix: trim ContractsJson type to only governance-relevant contracts
evgeniko Mar 27, 2026
e877da1
fix: trim contracts.json to only governance-relevant contract addresses
evgeniko Mar 27, 2026
2997b16
fix: move governance.ts out of SDK, address CI and review feedback
evgeniko Mar 27, 2026
cbfeff5
style: run prettier on all migrated files
evgeniko Mar 27, 2026
69c2af9
style: fix remaining prettier issues (match repo prettier 3.6.2)
evgeniko Mar 27, 2026
22bfeaa
fix: remove readTransceiverConfig and NttTransceiverProxies (not need…
evgeniko Mar 27, 2026
fe0aa64
fix: remove unused files (deployments.md, verify shell script, ntt co…
evgeniko Mar 27, 2026
797559b
fix: fix typos in error message and log output
evgeniko Mar 27, 2026
2c9b54d
fix: remove scripts that depend on old NTT SDK class (needs adaptatio…
evgeniko Mar 27, 2026
5a1fcca
fix: restore migrated governance script inputs
evgeniko Mar 27, 2026
d808335
refactor: move Solana scripts to separate private package
evgeniko Mar 27, 2026
a049830
fix: update lockfile, trim managers.json to used fields, fix prettier
evgeniko Mar 27, 2026
99f6787
fix: remove createGovernanceMessage script and its unused dependencies
evgeniko Mar 30, 2026
702cb47
fix: bump ethers to ^5.8.0 and pin elliptic to 6.6.1 for security fixes
evgeniko Mar 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 156 additions & 0 deletions deployments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
## NTT Deployment:
This document serves as an example of a possible order of execution of commands to perform a full deployment of NTT on Solana + one or more EVMs.

### Requirements:
NTT needs the following contracts to be able to operate. This doc assumes that these contracts are already deployed by the time you execute this deployment.

Deployed by NTT deployment owner:
- an ntt token

Deployed by wormhole:
- wormhole core layer
- wormhole relayer (you can use wormhole's public one or deploy your own)

### High level description of the process:
To have a multi-chain NTT setup working a few things need to happen.
- Deploy managers on EVM
- Register managers on NTT Token
- Deploy Transceivers on EVM
- Deploy NTT Program on Solana
- Set Mint authority to NTT program
- Initialize NTT program on Solana
- Cross register managers (let each manager know about the other managers)
- Cross register transceivers

## EVM Deployment:

### Environments & Configuration:
These scripts are implemented in way that helps keep track of the deployed addresses by reading contract addresses from json files that can be commited to the repository. Multiple environments are supported through the use of the `ENV` environment variable.
To create or use a new env all that needs to be done is to create a new directory on `evm/ts-scripts/config/<my-env>` with the name of the env you want to use and then set the environment variable ENV to the same value (ie on linux: `export ENV="my-env"`)
Inside the configuration directory, there needs to be a few files that will contain all the configuration you need to set up a full NTT deployment:
- `chains.json` contains the configuration used by the deployment runner such as what rpcs will be used or what chains will it run scripts against
- `contracts.json` this file contains the addresses of all contracts related to this deployment and will be used any time a script needs to know about the address of other of the contracts. Addresses of contracts will be written to this file as the deployment progress (ie after deploying managers we'll add the manager addresses here)
- `managers.json` contains the configuration that will be applied to managers
- `transceivers.json` contains the configuration that will be applied to transceivers
- `peers.json` contains the configuration that will be used for contract cross-registrations

> When a script deploys new contracts, it outputs the resulting addresseses on the directory `ts-scripts/output/<scripts-name>/<timestamp>.json (aside from logging them). Whenever we need to configure the addresses of a contract that we have just deployed we'll fetch the new addresses from those files.
Comment thread
evgeniko marked this conversation as resolved.
Outdated

### Deployment Steps:
- create/update `evm/config/<env>/contracts.json` as needed
- create/update `evm/config/<env>/managers.json` as needed
- create/update `evm/config/<env>/transceivers.json` as needed
- Set environment variables:
```
export FOUNDRY_PROFILE=prod
export WALLET_KEY="ledger"
export LEDGER_BIP32_PATH=""
export ENV=testnet
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
- Build:
```shell
make build-evm-prod
cd evm/ts-scripts
npm install
cd ..
npm --prefix ./ts-scripts run build # builds typescript bindings to evm/ts-scripts/output
```
- Deploy Managers:
```shell
bash -c ./ts-scripts/shell/deploy-managers.sh
#
# Use the addresses to update the `contracts.json` file
#
```
- Now that you have deployed your manager, you can go to your token deployment and configure the token to be managed by the managers you have deployed (aka, call `setMinter` on the token to the manager address).
- Deploy Transceivers:
```shell
bash -c ./ts-scripts/shell/deploy-transceivers.sh
#
# Use the addresses to update the `contracts.json` file
#
```
- Configure Managers:
```shell
bash -c ./ts-scripts/shell/configure-managers.sh
```

## Solana Deployment:
- set environment:
```shell
# Runner Configurations:
export SOLANA_RPC_URL=""
export WORMHOLE_PROGRAM_ID="" # wormhole core layer program id
export LEDGER_DERIVATION_PATH="" # derivation path

# Deployment configuration:
export MINT_ADDRESS="" # the program id of your spl token
```
- Create and set the pub key of the program:
```shell
solana-keygen grind --ignore-case --starts-with ntt:1
```
- use the pub key created to replace the `declare_id!` macro value on `lib.rs`
- export the pub-key of the program:
```
export NTT_PROGRAM_ID=<your-program-key>
```
- Build:
```
cd solana
anchor build --arch sbf -- --features "mainnet" # if you are deploying to tesnet, you should use "solana-devnet" instead of mainnet
```
- Deploy:
```
solana program -k usb://ledger?key=<your derivation path> deploy --url $SOLANA_RPC_URL --program-id "$NTT_PROGRAM_ID.json" target/deploy/example_native_token_transfers.so
```
- Initialize the program:
``` shell
make build
npx tsx ./ts/scripts/initializeNtt.ts
#
# The script will print the manager emitter address PDA. You can always derive
# this pda again, but might be easier if you take note of it at this point.
# You'll need it later to do cross-registrations.
#
```

## Cross Registrations:

### EVM cross Registrations:
- Create or update evm/config/<env>/peers.json (this file contains the data of all peers that the different evm deployments should know about. Note that the evm cross-registration script can find the addresses of its evm peers, but it can't find the solana peer address, so for solana you'll need to add two extra properties `managerAddress` and `transceiverAddress`. They correspond to the solana ntt deployment program-id and the manager-emitter-address PDA (the one printed during solana program initialization)
- Run update peers script:
```shell
bash -c ./ts-scripts/shell/update-peer-addresses.sh
```

### Solana Cross Registrations:
- update `evmNttDeployments` on solana/ts/scripts/env.ts with the addresses of your EVM managers and transceivers.
- Run cross registrations script:
```shell
npx tsx ./ts/scripts/updatePeers.ts
```

## Contract Bytecode Verification:

### EVM verification:
On evm there are scripts that verify the deployed contracts. To run them you'll need a file with the etherscan scanners keys per each of the supported chains.
Such file should have this structure:
```json
[
{
"chainId": 6,
"etherscan": "YOUR-ETTHERSCAN-API_KEY"
}
]
```
Run verification scripts:
```
export SCANNER_TOKENS_FILE_PATH="the/path/to/file/above"
bash -c ./evm/ts-scripts/shell/verify-managers.sh
bash -c ./evm/ts-scripts/shell/verify-transceivers.sh
```
Finally, go to the etherscan scanner of the different chains and link the verified proxy to the verified implementation.

### Solana Verification:
TODO
1 change: 1 addition & 0 deletions evm/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
forge-build
3 changes: 3 additions & 0 deletions evm/ts-scripts/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
WALLET_KEY=
LEDGER_BIP32_PATH=
GUARDIAN_KEY=
Comment thread
evgeniko marked this conversation as resolved.
4 changes: 4 additions & 0 deletions evm/ts-scripts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
output
contract-bindings
.env.testnet
.env.mainnet
Comment thread
coderabbitai[bot] marked this conversation as resolved.
2 changes: 1 addition & 1 deletion evm/ts-scripts/config/mainnet/chains.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"description": "MegaETH",
"evmNetworkId": 4326,
"chainId": 64,
"rpc": "https://mainnet.megaeth.com/rpc"
"rpc": "http://localhost:50444"
}
]
}
156 changes: 154 additions & 2 deletions evm/ts-scripts/config/mainnet/contracts.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,156 @@
{
"WormholeCoreContracts": [
{
"chainId": 2,
"address": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"
},
{
"chainId": 4,
"address": "0x98f3c9e6E3fAce36bAAd05FE09d375Ef1464288B"
},
{
"chainId": 6,
"address": "0x54a8e5f9c4CbA08F9943965859F6c34eAF03E26c"
},
{
"chainId": 23,
"address": "0xa5f208e072434bC67592E4C49C1B991BA79BCA46"
},
{
"chainId": 24,
"address": "0xEe91C335eab126dF5fDB3797EA9d6aD93aeC9722"
},
{
"chainId": 30,
"address": "0xbebdb6C8ddC678FfA9f8748f85C815C556Dd8ac6"
}
],
"WormholeRelayers": [
{
"chainId": 2,
"address": "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911"
},
{
"chainId": 23,
"address": "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911"
},
{
"chainId": 24,
"address": "0x27428DD2d3DD32A4D7f7C497eAaa23130d894911"
},
{
"chainId": 30,
"address": "0x706F82e9bb5b0813501714Ab5974216704980e31"
}
],
"SpecializedRelayers": [
{
"address": "0x63BE47835c7D66c4aA5B2C688Dc6ed9771c94C74",
"chainId": 2
},
{
"address": "0x63BE47835c7D66c4aA5B2C688Dc6ed9771c94C74",
"chainId": 23
},
{
"address": "0x63BE47835c7D66c4aA5B2C688Dc6ed9771c94C74",
"chainId": 24
},
{
"address": "0x63BE47835c7D66c4aA5B2C688Dc6ed9771c94C74",
"chainId": 30
}
],
"NttManagerImplementations": [
{
"address": "0x6883bdb0694751DE1545a1057c25b0F4fCC0443d",
"chainId": 2
},
{
"address": "0x23Fea5514DFC9821479fBE18BA1D7e1A61f6FfCf",
"chainId": 23
},
{
"address": "0x36CF4c88FA548c6Ad9fcDc696e1c27Bb3306163F",
"chainId": 24
},
{
"address": "0xc3a1248e9bdC1EEF81d16b2AD1594764cBd9307a",
"chainId": 30
}
],
"NttManagerProxies": [
{
"address": "0xc072B1AEf336eDde59A049699Ef4e8Fa9D594A48",
"chainId": 2
},
{
"address": "0x5333d0AcA64a450Add6FeF76D6D1375F726CB484",
"chainId": 23
},
{
"address": "0x1a4F1a790f23Ffb9772966cB6F36dCd658033e13",
"chainId": 24
},
{
"address": "0x5333d0AcA64a450Add6FeF76D6D1375F726CB484",
"chainId": 30
}
],
"TransceiverStructsLibs": [
{
"chainId": 2,
"address": "0x169D91C797edF56100F1B765268145660503a423"
},
{
"chainId": 23,
"address": "0x3b5CE72cf76dc9866aCc20DB51E4cAD3Eb719b0E"
},
{
"chainId": 24,
"address": "0x574B7864119C9223A9870Ea614dC91A8EE09E512"
},
{
"chainId": 30,
"address": "0x3b5CE72cf76dc9866aCc20DB51E4cAD3Eb719b0E"
}
],
"NttTransceiverImplementations": [
{
"address": "0x9bD8b7b527CA4e6738cBDaBdF51C22466756073d",
"chainId": 2
},
{
"address": "0x83F97c06dD151B0f8A8aB2629dEf30096443114E",
"chainId": 23
},
{
"address": "0xc072B1AEf336eDde59A049699Ef4e8Fa9D594A48",
"chainId": 24
},
{
"address": "0x83F97c06dD151B0f8A8aB2629dEf30096443114E",
"chainId": 30
}
],
"NttTransceiverProxies": [
{
"address": "0xDb55492d7190D1baE8ACbE03911C4E3E7426870c",
"chainId": 2
},
{
"address": "0xD1a8AB69e00266e8B791a15BC47514153A5045a6",
"chainId": 23
},
{
"address": "0x9bD8b7b527CA4e6738cBDaBdF51C22466756073d",
"chainId": 24
},
{
"address": "0xD1a8AB69e00266e8B791a15BC47514153A5045a6",
"chainId": 30
}
],
"GeneralPurposeGovernances": [
{
"address": "0x23Fea5514DFC9821479fBE18BA1D7e1A61f6FfCf",
Expand All @@ -7,7 +159,7 @@
{
"address": "0x8E4dc685e990379b8D53EcA47841E09B8d30043e",
"chainId": 4
},
}
{
Comment thread
evgeniko marked this conversation as resolved.
Outdated
"address": "0x169D91C797edF56100F1B765268145660503a423",
"chainId": 6
Expand Down Expand Up @@ -37,4 +189,4 @@
"chainId": 64
}
]
}
}
Loading
Loading