Skip to content

Commit 1854ea6

Browse files
authored
Feature: Native Token Transfers (NTT) integration (#1674)
* Feature: Native Token Transfers (NTT) integration Addresses #1585 * Use SDKv2 layouts for message parsing * renamed platforms -> chains * added sepolia cctp, removed goerli cctp * reworked ntt config, added ntt groups * usdc switch chains fix * custom ntt group support * abi version support, added 0.1.0 abis * Updated testnet addresses * updated testnet USDC.e address * rebased development * updated 0.1.0 ABI, avax-celo addresses * delivery price wormhole fee for manual xfers fix * removed comment * removed old testnet ntt token configs * Added NTT to README * Added Fantom bridged USDC NTT addresses
1 parent b5ebe15 commit 1854ea6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+15079
-139
lines changed

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,21 @@ See the "Arbitrary Token" example in [the config docs](https://docs.wormhole.com
131131

132132
Please note you have to [register a token](https://portalbridge.com/advanced-tools/#/register) with the token bridge before you can use it in Connect.
133133

134+
### Configuring Custom NTT (Native Token Transfer) Groups
135+
To configure custom NTT groups, include an `nttGroups` key in your configuration.
136+
137+
```ts
138+
const config: WormholeConnectConfig = {
139+
nttGroups: {
140+
// Your custom NTT groups go here
141+
}
142+
}
143+
```
144+
145+
For a practical example of how to structure your custom NTT groups, refer to the [nttGroups.ts](https://github.com/wormhole-foundation/wormhole-connect/blob/development/wormhole-connect/src/config/testnet/nttGroups.ts) file.
146+
147+
Please note that the `tokenKey` specified in your custom NTT group must correspond to an existing entry in the tokensConfig, whether it's a built-in or a custom token.
148+
134149
### Custom Theme
135150

136151
You can also customize Connect's color scheme by providing a `WormholeConnectTheme` as the `theme` prop.

builder/src/consts.ts

+14
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,20 @@ export const ROUTE_INFOS: RouteInfo[] = [
253253
title: "wstETH Bridge",
254254
description: "Permissionlessly transfer wstETH cross-chain with Wormhole.",
255255
},
256+
{
257+
key: "nttManual",
258+
title: "Native Token Transfer",
259+
description:
260+
"Permissionlessly transfer native tokens cross-chain with Wormhole.",
261+
link: "https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/README.md",
262+
},
263+
{
264+
key: "nttRelay",
265+
title: "Native Token Transfer Automatic Redeems",
266+
description:
267+
"Automatic redeems for Native Token Transfers powered by xLabs.",
268+
link: "https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/README.md",
269+
},
256270
];
257271
export const ROUTES = ROUTE_INFOS.map((r) => r.key);
258272

package-lock.json

+96-35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sdk/src/config/TESTNET.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,6 @@ const TESTNET: { [chain in TestnetChainName]: ChainConfig } = {
5555
contracts: {
5656
...CONTRACTS.TESTNET.ethereum,
5757
relayer: '0x9563a59c15842a6f322b10f69d1dd88b41f2e97b',
58-
cctpContracts: {
59-
cctpTokenMessenger: '0xd0c3da58f55358142b8d3e06c1c30c5c6114efe8',
60-
cctpMessageTransmitter: '0x26413e8157cd32011e726065a5462e97dd4d03d9',
61-
wormholeCircleRelayer: '0x17da1ff5386d044c63f00747b5b8ad1e3806448d',
62-
wormholeCCTP: '0x0a69146716b3a21622287efa1607424c663069a4',
63-
},
6458
},
6559
finalityThreshold: 64,
6660
nativeTokenDecimals: 18,
@@ -323,9 +317,14 @@ const TESTNET: { [chain in TestnetChainName]: ChainConfig } = {
323317
context: Context.ETH,
324318
contracts: {
325319
...CONTRACTS.TESTNET.sepolia,
320+
cctpContracts: {
321+
cctpTokenMessenger: '0x9f3b8679c73c2fef8b59b4f3444d4e156fb70aa5',
322+
cctpMessageTransmitter: '0x7865fafc2db2093669d92c0f33aeef291086befd',
323+
},
326324
},
327325
finalityThreshold: 0,
328326
nativeTokenDecimals: 18,
327+
cctpDomain: 0,
329328
},
330329
arbitrum_sepolia: {
331330
key: 'arbitrum_sepolia',
@@ -397,7 +396,7 @@ const TESTNET_CONFIG: WormholeConfig = {
397396
klaytn: 'https://rpc.ankr.com/klaytn_testnet',
398397
sepolia: 'https://rpc.ankr.com/eth_sepolia',
399398
arbitrum_sepolia: 'https://sepolia-rollup.arbitrum.io/rpc',
400-
base_sepolia: 'https://sepolia.base.org',
399+
base_sepolia: 'https://base-sepolia-rpc.publicnode.com',
401400
optimism_sepolia: 'https://sepolia.optimism.io',
402401
},
403402
rest: {

wormhole-connect/package.json

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
],
1919
"dependencies": {
2020
"@certusone/wormhole-sdk": "^0.10.10",
21+
"@coral-xyz/anchor": "^0.29.0",
2122
"@cosmjs/cosmwasm-stargate": "^0.31.3",
2223
"@cosmjs/stargate": "^0.31.3",
2324
"@cosmjs/tendermint-rpc": "^0.31.3",
@@ -30,7 +31,7 @@
3031
"@reduxjs/toolkit": "^1.9.1",
3132
"@solana/wallet-adapter-wallets": "^0.19.25",
3233
"@solana/web3.js": "^1.73.0",
33-
"@wormhole-foundation/sdk-definitions": "^0.5.0",
34+
"@wormhole-foundation/sdk-definitions": "^0.5.2-beta.0",
3435
"@xlabs-libs/wallet-aggregator-aptos": "^0.0.1-alpha.14",
3536
"@xlabs-libs/wallet-aggregator-core": "^0.0.1-alpha.18",
3637
"@xlabs-libs/wallet-aggregator-cosmos": "^0.0.1-alpha.14",
@@ -62,7 +63,8 @@
6263
"prettier": "prettier --write ./src",
6364
"analyze": "NODE_ENV=production NODE_OPTIONS=--max-old-space-size=6144 vite-bundle-visualizer",
6465
"test": "jest ./tests/*.test.ts --detectOpenHandles",
65-
"checksdn": "npx tsx scripts/ofac/checkSdnListForUpdates.ts"
66+
"checksdn": "npx tsx scripts/ofac/checkSdnListForUpdates.ts",
67+
"preview": "vite preview"
6668
},
6769
"eslintConfig": {
6870
"extends": [

wormhole-connect/src/AppRouter.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import { setRoute } from './store/router';
1919
import { clearWallets } from './store/wallet';
2020
import { clearPorticoBridge } from 'store/porticoBridge';
2121
import { useExternalSearch } from 'hooks/useExternalSearch';
22+
import { clearNtt } from 'store/ntt';
23+
import internalConfig from 'config';
2224

2325
const useStyles = makeStyles()((theme: any) => ({
2426
appContent: {
@@ -71,6 +73,8 @@ function AppRouter({ config }: Props) {
7173
if (prevRoute === redeemRoute && route !== redeemRoute) {
7274
dispatch(clearRedeem());
7375
dispatch(clearWallets());
76+
dispatch(clearNtt());
77+
internalConfig.wh.registerProviders(); // reset providers that may have been set during transfer
7478
}
7579
// reset transfer state on leave
7680
if (prevRoute === bridgeRoute && route !== bridgeRoute) {

wormhole-connect/src/config/devnet/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
DEVNET_RPC_MAPPING,
88
} from './rpcs';
99
import { DEVNET_TOKENS } from './tokens';
10+
import { DEVNET_NTT_GROUPS } from './nttGroups';
1011

1112
export * from './chains';
1213
export * from './gasEstimates';
@@ -20,6 +21,7 @@ const DEVNET: NetworkData = {
2021
rpcs: DEVNET_RPC_MAPPING,
2122
rest: DEVNET_REST_MAPPING,
2223
graphql: DEVNET_GRAPHQL_MAPPING,
24+
nttGroups: DEVNET_NTT_GROUPS,
2325
};
2426

2527
export default DEVNET;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { NttGroups } from 'config/types';
2+
3+
export const DEVNET_NTT_GROUPS: NttGroups = {};

wormhole-connect/src/config/index.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ import TESTNET from './testnet';
1111
import DEVNET from './devnet';
1212
import type { WormholeConnectConfig } from './types';
1313
import { Network, InternalConfig, Route, TokensConfig } from './types';
14-
import { mergeCustomTokensConfig, validateDefaults } from './utils';
14+
import {
15+
mergeCustomTokensConfig,
16+
mergeNttGroups,
17+
validateDefaults,
18+
} from './utils';
1519

1620
export function buildConfig(
1721
customConfig?: WormholeConnectConfig,
@@ -132,6 +136,13 @@ export function buildConfig(
132136
// Route options
133137
ethBridgeMaxAmount: customConfig?.ethBridgeMaxAmount ?? 5,
134138
wstETHBridgeMaxAmount: customConfig?.wstETHBridgeMaxAmount ?? 5,
139+
140+
// NTT config
141+
nttGroups: mergeNttGroups(
142+
tokens,
143+
networkData.nttGroups,
144+
customConfig?.nttGroups,
145+
),
135146
};
136147
}
137148

wormhole-connect/src/config/mainnet/gasEstimates.ts

+14
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ export const MAINNET_GAS_ESTIMATES: GasEstimates = {
3232
sendToken: 300000,
3333
claim: 450000,
3434
},
35+
[Route.NttManual]: {
36+
sendToken: 10000000,
37+
claim: 10000000,
38+
},
39+
[Route.NttRelay]: {
40+
sendToken: 10000000,
41+
},
3542
},
3643
polygon: {
3744
[Route.Bridge]: {
@@ -107,6 +114,13 @@ export const MAINNET_GAS_ESTIMATES: GasEstimates = {
107114
sendNative: 250000,
108115
sendToken: 300000,
109116
},
117+
[Route.NttManual]: {
118+
sendToken: 10000000,
119+
claim: 10000000,
120+
},
121+
[Route.NttRelay]: {
122+
sendToken: 10000000,
123+
},
110124
},
111125
celo: {
112126
[Route.Bridge]: {

wormhole-connect/src/config/mainnet/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
MAINNET_RPC_MAPPING,
88
} from './rpcs';
99
import { MAINNET_TOKENS } from './tokens';
10+
import { MAINNET_NTT_GROUPS } from './nttGroups';
1011

1112
export * from './chains';
1213
export * from './gasEstimates';
@@ -20,6 +21,7 @@ const MAINNET: NetworkData = {
2021
rpcs: MAINNET_RPC_MAPPING,
2122
rest: MAINNET_REST_MAPPING,
2223
graphql: MAINNET_GRAPHQL_MAPPING,
24+
nttGroups: MAINNET_NTT_GROUPS,
2325
};
2426

2527
export default MAINNET;

0 commit comments

Comments
 (0)