Skip to content

Commit 274ec00

Browse files
committed
break out consts to separate file, add createAta fn to redeem
1 parent b44b92f commit 274ec00

File tree

7 files changed

+111
-113
lines changed

7 files changed

+111
-113
lines changed

sdk/examples/src/automaticRoute.ts

+10-52
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,14 @@
1-
import {
2-
Chain,
3-
canonicalAddress,
4-
routes,
5-
wormhole,
6-
} from "@wormhole-foundation/sdk";
1+
import { canonicalAddress, routes, wormhole } from "@wormhole-foundation/sdk";
72
import evm from "@wormhole-foundation/sdk/evm";
83
import solana from "@wormhole-foundation/sdk/solana";
94

105
// register protocol implementations
11-
import { Ntt } from "@wormhole-foundation/sdk-definitions-ntt";
126
import "@wormhole-foundation/sdk-evm-ntt";
137
import "@wormhole-foundation/sdk-solana-ntt";
148

15-
import {
16-
NttRoute,
17-
nttAutomaticRoute,
18-
} from "@wormhole-foundation/sdk-route-ntt";
9+
import { nttAutomaticRoute } from "@wormhole-foundation/sdk-route-ntt";
1910
import { getSigner } from "./helpers.js";
20-
21-
const NTT_CONTRACTS: Record<string, Ntt.Contracts> = {
22-
Solana: {
23-
token: "E3W7KwMH8ptaitYyWtxmfBUpqcuf2XieaFtQSn1LVXsA",
24-
manager: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
25-
transceiver: {
26-
wormhole: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
27-
},
28-
quoter: "Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ",
29-
},
30-
ArbitrumSepolia: {
31-
token: "0x87579Dc40781e99b870DDce46e93bd58A0e58Ae5",
32-
manager: "0xdA5a8e05e276AAaF4d79AB5b937a002E5221a4D8",
33-
transceiver: {
34-
wormhole: "0xd2940c256a3D887833D449eF357b6D639Cb98e12",
35-
},
36-
},
37-
};
38-
39-
// Reformat NTT contracts to fit token list list
40-
const tokens = {
41-
Jito: Object.entries(NTT_CONTRACTS).map(([c, contracts]) => {
42-
const chain = c as Chain;
43-
const { token, manager, transceiver: transceivers, quoter } = contracts;
44-
const transceiver = Object.entries(transceivers).map(([k, v]) => {
45-
return { type: k as NttRoute.TransceiverType, address: v };
46-
});
47-
48-
return { chain, token, manager, quoter, transceiver };
49-
}),
50-
};
11+
import { NttTokens } from "./consts.js";
5112

5213
(async function () {
5314
const wh = await wormhole("Testnet", [solana, evm]);
@@ -58,7 +19,7 @@ const tokens = {
5819
const srcSigner = await getSigner(src);
5920
const dstSigner = await getSigner(dst);
6021

61-
const resolver = wh.resolver([nttAutomaticRoute({ tokens })]);
22+
const resolver = wh.resolver([nttAutomaticRoute({ tokens: NttTokens })]);
6223

6324
const srcTokens = await resolver.supportedSourceTokens(src);
6425
console.log(
@@ -112,9 +73,7 @@ const tokens = {
11273
// this new var must be passed to the next step, quote
11374
const validated = await bestRoute.validate({
11475
amount: "0.00001",
115-
options: {
116-
gasDropoff: "0.0000001",
117-
},
76+
options: { gasDropoff: "0.0" },
11877
});
11978
if (!validated.valid) throw validated.error;
12079
console.log("Validated parameters: ", validated.params);
@@ -125,13 +84,12 @@ const tokens = {
12584
if (!quote.success) throw quote.error;
12685
console.log("Best route quote: ", quote);
12786

128-
return;
12987
// Now the transfer may be initiated
13088
// A receipt will be returned, guess what you gotta do with that?
131-
//const receipt = await bestRoute.initiate(srcSigner.signer, quote);
132-
//console.log("Initiated transfer with receipt: ", receipt);
89+
const receipt = await bestRoute.initiate(srcSigner.signer, quote);
90+
console.log("Initiated transfer with receipt: ", receipt);
13391

134-
//// Kick off a wait log, if there is an opportunity to complete, this function will do it
135-
//// see the implementation for how this works
136-
//await routes.checkAndCompleteTransfer(bestRoute, receipt, dstSigner.signer);
92+
// Kick off a wait log, if there is an opportunity to complete, this function will do it
93+
// see the implementation for how this works
94+
await routes.checkAndCompleteTransfer(bestRoute, receipt, dstSigner.signer);
13795
})();

sdk/examples/src/consts.ts

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Chain } from "@wormhole-foundation/sdk";
2+
import { Ntt } from "@wormhole-foundation/sdk-definitions-ntt";
3+
import { NttRoute } from "@wormhole-foundation/sdk-route-ntt";
4+
type NttContracts = {
5+
[key in Chain]?: Ntt.Contracts;
6+
};
7+
8+
export const JITO_NTT_CONTRACTS: NttContracts = {
9+
Solana: {
10+
token: "E3W7KwMH8ptaitYyWtxmfBUpqcuf2XieaFtQSn1LVXsA",
11+
manager: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
12+
transceiver: { wormhole: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f" },
13+
quoter: "Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ",
14+
},
15+
ArbitrumSepolia: {
16+
token: "0x87579Dc40781e99b870DDce46e93bd58A0e58Ae5",
17+
manager: "0xdA5a8e05e276AAaF4d79AB5b937a002E5221a4D8",
18+
transceiver: { wormhole: "0xd2940c256a3D887833D449eF357b6D639Cb98e12" },
19+
},
20+
};
21+
22+
export const TEST_NTT_TOKENS: NttContracts = {
23+
Sepolia: {
24+
token: "0x738141EFf659625F2eAD4feECDfCD94155C67f18",
25+
manager: "0x06413c42e913327Bc9a08B7C1E362BAE7C0b9598",
26+
transceiver: { wormhole: "0x649fF7B32C2DE771043ea105c4aAb2D724497238" },
27+
},
28+
ArbitrumSepolia: {
29+
token: "0x395D3C74232D12916ecA8952BA352b4d27818035",
30+
manager: "0xCeC6FB4F352bf3DC2b95E1c41831E4D2DBF9a35D",
31+
transceiver: { wormhole: "0xfA42603152E4f133F5F3DA610CDa91dF5821d8bc" },
32+
},
33+
OptimismSepolia: {
34+
token: "0x1d30E78B7C7fbbcef87ae6e97B5389b2e470CA4a",
35+
manager: "0x27F9Fdd3eaD5aA9A5D827Ca860Be28442A1e7582",
36+
transceiver: { wormhole: "0xeCF0496DE01e9Aa4ADB50ae56dB550f52003bdB7" },
37+
},
38+
BaseSepolia: {
39+
token: "0xdDFeABcCf2063CD66f53a1218e23c681Ba6e7962",
40+
manager: "0x8b9E328bE1b1Bc7501B413d04EBF7479B110775c",
41+
transceiver: { wormhole: "0x149987472333cD48ac6D28293A338a1EEa6Be7EE" },
42+
},
43+
Solana: {
44+
token: "EetppHswYvV1jjRWoQKC1hejdeBDHR9NNzNtCyRQfrrQ",
45+
manager: "NTtAaoDJhkeHeaVUHnyhwbPNAN6WgBpHkHBTc6d7vLK",
46+
transceiver: { wormhole: "NTtAaoDJhkeHeaVUHnyhwbPNAN6WgBpHkHBTc6d7vLK" },
47+
quoter: "Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ",
48+
},
49+
};
50+
51+
// Reformat NTT contracts to fit TokenConfig for Route
52+
function reformat(contracts: NttContracts) {
53+
return Object.entries(TEST_NTT_TOKENS).map(([chain, contracts]) => {
54+
const { token, manager, transceiver: xcvrs, quoter } = contracts;
55+
const transceiver = Object.entries(xcvrs).map(([k, v]) => {
56+
return { type: k as NttRoute.TransceiverType, address: v };
57+
});
58+
return { chain: chain as Chain, token, manager, quoter, transceiver };
59+
});
60+
}
61+
62+
export const NttTokens = {
63+
Test: reformat(TEST_NTT_TOKENS),
64+
};

sdk/examples/src/helpers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export async function getSigner<N extends Network, C extends Chain>(
3030
signer = await solana.getSigner(
3131
await chain.getRpc(),
3232
getEnv("OTHER_SOL_PRIVATE_KEY"),
33-
{ priorityFeePercentile: 0.9 }
33+
{ priorityFeePercentile: 0.9, debug: true }
3434
);
3535
break;
3636
case "Evm":

sdk/examples/src/index.ts

+3-16
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,12 @@ import evm from "@wormhole-foundation/sdk/evm";
77
import solana from "@wormhole-foundation/sdk/solana";
88

99
// register protocol implementations
10-
import { Ntt } from "@wormhole-foundation/sdk-definitions-ntt";
1110
import "@wormhole-foundation/sdk-evm-ntt";
1211
import "@wormhole-foundation/sdk-solana-ntt";
1312

13+
import { TEST_NTT_TOKENS } from "./consts.js";
1414
import { getSigner } from "./helpers.js";
1515

16-
const NTT_CONTRACTS: Record<string, Ntt.Contracts> = {
17-
Solana: {
18-
token: "E3W7KwMH8ptaitYyWtxmfBUpqcuf2XieaFtQSn1LVXsA",
19-
manager: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
20-
transceiver: { wormhole: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f" },
21-
},
22-
ArbitrumSepolia: {
23-
token: "0x87579Dc40781e99b870DDce46e93bd58A0e58Ae5",
24-
manager: "0xdA5a8e05e276AAaF4d79AB5b937a002E5221a4D8",
25-
transceiver: { wormhole: "0xd2940c256a3D887833D449eF357b6D639Cb98e12" },
26-
},
27-
};
28-
2916
// Recover an in-flight transfer by setting txids here from output of previous run
3017
const recoverTxids: TransactionId[] = [
3118
// { chain: "Solana", txid: "hZXRs9TEvMWnSAzcgmrEuHsq1C5rbcompy63vkJ2SrXv4a7u6ZBEaJAkBMXKAfScCooDNhN36Jt4PMcDhN8yGjP", },
@@ -40,10 +27,10 @@ const recoverTxids: TransactionId[] = [
4027
const dstSigner = await getSigner(dst);
4128

4229
const srcNtt = await src.getProtocol("Ntt", {
43-
ntt: NTT_CONTRACTS[src.chain],
30+
ntt: TEST_NTT_TOKENS[src.chain],
4431
});
4532
const dstNtt = await dst.getProtocol("Ntt", {
46-
ntt: NTT_CONTRACTS[dst.chain],
33+
ntt: TEST_NTT_TOKENS[dst.chain],
4734
});
4835

4936
// Initiate the transfer (or set to recoverTxids to complete transfer)

sdk/examples/src/manualRoute.ts

+4-43
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,15 @@
1-
import {
2-
Chain,
3-
canonicalAddress,
4-
routes,
5-
wormhole,
6-
} from "@wormhole-foundation/sdk";
1+
import { canonicalAddress, routes, wormhole } from "@wormhole-foundation/sdk";
72
import evm from "@wormhole-foundation/sdk/evm";
83
import solana from "@wormhole-foundation/sdk/solana";
94

105
// register protocol implementations
11-
import { Ntt } from "@wormhole-foundation/sdk-definitions-ntt";
126
import "@wormhole-foundation/sdk-evm-ntt";
137
import "@wormhole-foundation/sdk-solana-ntt";
148

15-
import { NttRoute, nttManualRoute } from "@wormhole-foundation/sdk-route-ntt";
9+
import { nttManualRoute } from "@wormhole-foundation/sdk-route-ntt";
10+
import { NttTokens } from "./consts.js";
1611
import { getSigner } from "./helpers.js";
1712

18-
const NTT_CONTRACTS: Record<string, Ntt.Contracts> = {
19-
Solana: {
20-
token: "E3W7KwMH8ptaitYyWtxmfBUpqcuf2XieaFtQSn1LVXsA",
21-
manager: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
22-
transceiver: {
23-
wormhole: "WZLm4bJU4BNVmzWEwEzGVMQ5XFUc4iBmMSLutFbr41f",
24-
},
25-
},
26-
ArbitrumSepolia: {
27-
token: "0x87579Dc40781e99b870DDce46e93bd58A0e58Ae5",
28-
manager: "0xdA5a8e05e276AAaF4d79AB5b937a002E5221a4D8",
29-
transceiver: {
30-
wormhole: "0xd2940c256a3D887833D449eF357b6D639Cb98e12",
31-
},
32-
},
33-
};
34-
35-
// Reformat NTT contracts to fit token list list
36-
const tokens = {
37-
Jito: Object.entries(NTT_CONTRACTS).map(([chain, contracts]) => {
38-
return {
39-
chain: chain as Chain,
40-
token: contracts.token,
41-
manager: contracts.manager,
42-
transceiver: [
43-
{
44-
type: "wormhole",
45-
address: contracts.transceiver.wormhole,
46-
},
47-
],
48-
} as NttRoute.TokenConfig;
49-
}),
50-
};
51-
5213
(async function () {
5314
const wh = await wormhole("Testnet", [solana, evm]);
5415

@@ -58,7 +19,7 @@ const tokens = {
5819
const srcSigner = await getSigner(src);
5920
const dstSigner = await getSigner(dst);
6021

61-
const resolver = wh.resolver([nttManualRoute({ tokens })]);
22+
const resolver = wh.resolver([nttManualRoute({ tokens: NttTokens })]);
6223

6324
const srcTokens = await resolver.supportedSourceTokens(src);
6425
console.log(

sdk/route/src/automatic.ts

+1
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ export class NttAutomaticRoute<N extends Network>
173173
const ntt = await fromChain.getProtocol("Ntt", {
174174
ntt: params.normalizedParams.sourceContracts,
175175
});
176+
176177
const initXfer = ntt.transfer(
177178
sender,
178179
amount.units(params.normalizedParams.amount),

sdk/solana/src/ntt.ts

+28-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Program } from "@coral-xyz/anchor";
22
import { associatedAddress } from "@coral-xyz/anchor/dist/cjs/utils/token.js";
33
import * as splToken from "@solana/spl-token";
4-
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
4+
import {
5+
createAssociatedTokenAccountInstruction,
6+
getAssociatedTokenAddressSync,
7+
} from "@solana/spl-token";
58
import {
69
Connection,
710
Keypair,
@@ -410,6 +413,7 @@ export class SolanaNtt<N extends Network, C extends SolanaChains>
410413

411414
const senderAddress = new SolanaAddress(sender).unwrap();
412415
const fromAuthority = senderAddress;
416+
console.log(config.mint);
413417
const from = getAssociatedTokenAddressSync(config.mint, fromAuthority);
414418

415419
const transferArgs: TransferArgs = {
@@ -474,6 +478,26 @@ export class SolanaNtt<N extends Network, C extends SolanaChains>
474478
);
475479
}
476480

481+
private async *createAta(sender: AccountAddress<C>, mint: PublicKey) {
482+
const senderAddress = new SolanaAddress(sender).unwrap();
483+
const ata = getAssociatedTokenAddressSync(mint, senderAddress);
484+
485+
// If the ata doesn't exist yet, create it
486+
const acctInfo = await this.connection.getAccountInfo(ata);
487+
if (acctInfo === null) {
488+
const transaction = new Transaction().add(
489+
createAssociatedTokenAccountInstruction(
490+
senderAddress,
491+
ata,
492+
senderAddress,
493+
mint
494+
)
495+
);
496+
transaction.feePayer = senderAddress;
497+
yield this.createUnsignedTx({ transaction }, "Redeem.CreateATA");
498+
}
499+
}
500+
477501
async *redeem(attestations: Ntt.Attestation[], payer: AccountAddress<C>) {
478502
const config = await this.getConfig();
479503
if (config.paused) throw new Error("Contract is paused");
@@ -482,6 +506,9 @@ export class SolanaNtt<N extends Network, C extends SolanaChains>
482506
// if (attestations.length !== this.xcvrs.length) throw "No";
483507
const wormholeNTT = attestations[0]! as WormholeNttTransceiver.VAA;
484508

509+
// Create the vaa if necessary
510+
yield* this.createAta(payer, config.mint);
511+
485512
// Post the VAA that we intend to redeem
486513
yield* this.core.postVaa(payer, wormholeNTT);
487514

0 commit comments

Comments
 (0)