@m0-foundation/ntt-sdk-route 0.0.13 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +274 -58
- package/dist/index.mjs +274 -60
- package/package.json +16 -15
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Network, routes, Chain, ChainContext, TokenId, Signer, ChainAddress, AccountAddress } from '@wormhole-foundation/sdk-connect';
|
|
2
|
-
import { Ntt } from '@wormhole-foundation/sdk-definitions-ntt';
|
|
2
|
+
import { Ntt, NttWithExecutor } from '@wormhole-foundation/sdk-definitions-ntt';
|
|
3
3
|
import { EvmNtt } from '@wormhole-foundation/sdk-evm-ntt';
|
|
4
4
|
import { SolanaNtt } from '@wormhole-foundation/sdk-solana-ntt';
|
|
5
5
|
import { EvmChains, EvmUnsignedTransaction } from '@wormhole-foundation/sdk-evm';
|
|
@@ -21,6 +21,7 @@ type Contracts = Ntt.Contracts & {
|
|
|
21
21
|
declare class M0AutomaticRoute<N extends Network> extends routes.AutomaticRoute<N, Op, Vp, R> implements routes.StaticRouteMethods<typeof M0AutomaticRoute> {
|
|
22
22
|
static NATIVE_GAS_DROPOFF_SUPPORTED: boolean;
|
|
23
23
|
static EVM_WRAPPED_M_TOKEN: string;
|
|
24
|
+
static EXECUTOR_ENTRYPOINT: string;
|
|
24
25
|
static EVM_CONTRACTS: Contracts;
|
|
25
26
|
static meta: {
|
|
26
27
|
name: string;
|
|
@@ -46,6 +47,8 @@ declare class M0AutomaticRoute<N extends Network> extends routes.AutomaticRoute<
|
|
|
46
47
|
createUnsignedTx<N extends Network, C extends EvmChains>(ntt: EvmNtt<N, C>, txReq: TransactionRequest, description: string, parallelizable?: boolean): EvmUnsignedTransaction<N, C>;
|
|
47
48
|
transferSolanaExtension<N extends Network, C extends SolanaChains>(ntt: SolanaNtt<N, C>, sender: AccountAddress<C>, amount: bigint, recipient: ChainAddress, sourceToken: string, destinationToken: string, options: Ntt.TransferOptions, outboxItem?: Keypair): AsyncGenerator<SolanaUnsignedTransaction<N, C>>;
|
|
48
49
|
track(receipt: R, timeout?: number): AsyncGenerator<R, void, unknown>;
|
|
50
|
+
private getExecutorQuote;
|
|
51
|
+
private requiresExecutor;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
type SvmNetwork = Exclude<Network, "Devnet">;
|
|
@@ -61,10 +64,14 @@ declare class SolanaRoutes<N extends Network, C extends SolanaChains> {
|
|
|
61
64
|
constructor(ntt: SolanaNtt<N, C>);
|
|
62
65
|
private static getPrograms;
|
|
63
66
|
private static getExtPrograms;
|
|
64
|
-
static getSolanaContracts(
|
|
67
|
+
static getSolanaContracts(network: Network, chain: SolanaChains): Ntt.Contracts & {
|
|
68
|
+
mLikeTokens: string[];
|
|
69
|
+
};
|
|
70
|
+
getSolanaContracts(): Ntt.Contracts & {
|
|
65
71
|
mLikeTokens: string[];
|
|
66
72
|
};
|
|
67
73
|
getTransferExtensionBurnIx(amount: bigint, recipient: ChainAddress, payer: PublicKey, outboxItem: PublicKey, extMint: PublicKey, destinationToken: Uint8Array, shouldQueue?: boolean): TransactionInstruction;
|
|
74
|
+
getExecutorRelayIx(sender: PublicKey, quote: NttWithExecutor.Quote, destinationChain: Chain, outboxItem: PublicKey): TransactionInstruction;
|
|
68
75
|
getReleaseInboundMintExtensionIx(nttMessage: Ntt.Message, emitterChain: Chain, payer: PublicKey, extMint: PublicKey, extAta: PublicKey): TransactionInstruction;
|
|
69
76
|
getAddressLookupTableAccounts(connection: Connection): Promise<AddressLookupTableAccount>;
|
|
70
77
|
static createReleaseInboundMintInstruction<N extends Network, C extends SolanaChains>(ntt: SolanaNtt<N, C>, args: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Network, routes, Chain, ChainContext, TokenId, Signer, ChainAddress, AccountAddress } from '@wormhole-foundation/sdk-connect';
|
|
2
|
-
import { Ntt } from '@wormhole-foundation/sdk-definitions-ntt';
|
|
2
|
+
import { Ntt, NttWithExecutor } from '@wormhole-foundation/sdk-definitions-ntt';
|
|
3
3
|
import { EvmNtt } from '@wormhole-foundation/sdk-evm-ntt';
|
|
4
4
|
import { SolanaNtt } from '@wormhole-foundation/sdk-solana-ntt';
|
|
5
5
|
import { EvmChains, EvmUnsignedTransaction } from '@wormhole-foundation/sdk-evm';
|
|
@@ -21,6 +21,7 @@ type Contracts = Ntt.Contracts & {
|
|
|
21
21
|
declare class M0AutomaticRoute<N extends Network> extends routes.AutomaticRoute<N, Op, Vp, R> implements routes.StaticRouteMethods<typeof M0AutomaticRoute> {
|
|
22
22
|
static NATIVE_GAS_DROPOFF_SUPPORTED: boolean;
|
|
23
23
|
static EVM_WRAPPED_M_TOKEN: string;
|
|
24
|
+
static EXECUTOR_ENTRYPOINT: string;
|
|
24
25
|
static EVM_CONTRACTS: Contracts;
|
|
25
26
|
static meta: {
|
|
26
27
|
name: string;
|
|
@@ -46,6 +47,8 @@ declare class M0AutomaticRoute<N extends Network> extends routes.AutomaticRoute<
|
|
|
46
47
|
createUnsignedTx<N extends Network, C extends EvmChains>(ntt: EvmNtt<N, C>, txReq: TransactionRequest, description: string, parallelizable?: boolean): EvmUnsignedTransaction<N, C>;
|
|
47
48
|
transferSolanaExtension<N extends Network, C extends SolanaChains>(ntt: SolanaNtt<N, C>, sender: AccountAddress<C>, amount: bigint, recipient: ChainAddress, sourceToken: string, destinationToken: string, options: Ntt.TransferOptions, outboxItem?: Keypair): AsyncGenerator<SolanaUnsignedTransaction<N, C>>;
|
|
48
49
|
track(receipt: R, timeout?: number): AsyncGenerator<R, void, unknown>;
|
|
50
|
+
private getExecutorQuote;
|
|
51
|
+
private requiresExecutor;
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
type SvmNetwork = Exclude<Network, "Devnet">;
|
|
@@ -61,10 +64,14 @@ declare class SolanaRoutes<N extends Network, C extends SolanaChains> {
|
|
|
61
64
|
constructor(ntt: SolanaNtt<N, C>);
|
|
62
65
|
private static getPrograms;
|
|
63
66
|
private static getExtPrograms;
|
|
64
|
-
static getSolanaContracts(
|
|
67
|
+
static getSolanaContracts(network: Network, chain: SolanaChains): Ntt.Contracts & {
|
|
68
|
+
mLikeTokens: string[];
|
|
69
|
+
};
|
|
70
|
+
getSolanaContracts(): Ntt.Contracts & {
|
|
65
71
|
mLikeTokens: string[];
|
|
66
72
|
};
|
|
67
73
|
getTransferExtensionBurnIx(amount: bigint, recipient: ChainAddress, payer: PublicKey, outboxItem: PublicKey, extMint: PublicKey, destinationToken: Uint8Array, shouldQueue?: boolean): TransactionInstruction;
|
|
74
|
+
getExecutorRelayIx(sender: PublicKey, quote: NttWithExecutor.Quote, destinationChain: Chain, outboxItem: PublicKey): TransactionInstruction;
|
|
68
75
|
getReleaseInboundMintExtensionIx(nttMessage: Ntt.Message, emitterChain: Chain, payer: PublicKey, extMint: PublicKey, extAta: PublicKey): TransactionInstruction;
|
|
69
76
|
getAddressLookupTableAccounts(connection: Connection): Promise<AddressLookupTableAccount>;
|
|
70
77
|
static createReleaseInboundMintInstruction<N extends Network, C extends SolanaChains>(ntt: SolanaNtt<N, C>, args: {
|
package/dist/index.js
CHANGED
|
@@ -2,19 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
var sdkConnect = require('@wormhole-foundation/sdk-connect');
|
|
4
4
|
var sdkDefinitionsNtt = require('@wormhole-foundation/sdk-definitions-ntt');
|
|
5
|
-
var sdkSolanaNtt = require('@wormhole-foundation/sdk-solana-ntt');
|
|
6
5
|
var sdkEvm = require('@wormhole-foundation/sdk-evm');
|
|
7
6
|
var sdkSolana = require('@wormhole-foundation/sdk-solana');
|
|
8
7
|
var sdkRouteNtt = require('@wormhole-foundation/sdk-route-ntt');
|
|
9
8
|
var ethers = require('ethers');
|
|
10
9
|
var web3_js = require('@solana/web3.js');
|
|
11
10
|
var splToken = require('@solana/spl-token');
|
|
11
|
+
var sdkSolanaNtt = require('@wormhole-foundation/sdk-solana-ntt');
|
|
12
12
|
var BN = require('bn.js');
|
|
13
13
|
var sha2 = require('@noble/hashes/sha2');
|
|
14
|
+
var evm = require('@wormhole-foundation/sdk/platforms/evm');
|
|
15
|
+
var solana = require('@wormhole-foundation/sdk/platforms/solana');
|
|
14
16
|
|
|
15
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
18
|
|
|
17
19
|
var BN__default = /*#__PURE__*/_interopDefault(BN);
|
|
20
|
+
var evm__default = /*#__PURE__*/_interopDefault(evm);
|
|
21
|
+
var solana__default = /*#__PURE__*/_interopDefault(solana);
|
|
18
22
|
|
|
19
23
|
// src/m0AutomaticRoute.ts
|
|
20
24
|
var SolanaRoutes = class _SolanaRoutes {
|
|
@@ -22,7 +26,10 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
22
26
|
this.ntt = ntt;
|
|
23
27
|
this.network = ntt.network;
|
|
24
28
|
this.programs = _SolanaRoutes.getPrograms(this.network);
|
|
25
|
-
this.extPrograms = _SolanaRoutes.getExtPrograms(
|
|
29
|
+
this.extPrograms = _SolanaRoutes.getExtPrograms(
|
|
30
|
+
this.network,
|
|
31
|
+
this.ntt.chain
|
|
32
|
+
);
|
|
26
33
|
}
|
|
27
34
|
static getPrograms(network) {
|
|
28
35
|
return {
|
|
@@ -30,7 +37,7 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
30
37
|
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
31
38
|
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
32
39
|
lut: pk("9JLRqBqkznKiSoNfotA4ywSRdnWb2fE76SiFrAfkaRCD"),
|
|
33
|
-
mMint: pk("
|
|
40
|
+
mMint: pk("mzerojk9tg56ebsrEAhfkyc9VgKjTW2zDqp6C5mhjzH"),
|
|
34
41
|
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
35
42
|
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
36
43
|
},
|
|
@@ -38,13 +45,21 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
38
45
|
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
39
46
|
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
40
47
|
lut: pk("6GhuWPuAmiJeeSVsr58KjqHcAejJRndCx9BVtHkaYHUR"),
|
|
41
|
-
mMint: pk("
|
|
48
|
+
mMint: pk("mzerojk9tg56ebsrEAhfkyc9VgKjTW2zDqp6C5mhjzH"),
|
|
42
49
|
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
43
50
|
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
44
51
|
}
|
|
45
52
|
}[network];
|
|
46
53
|
}
|
|
47
|
-
static getExtPrograms(network) {
|
|
54
|
+
static getExtPrograms(network, chain) {
|
|
55
|
+
if (chain === "Fogo") {
|
|
56
|
+
return {
|
|
57
|
+
fUSDqquEMUU8UmU2YWYGZy2Lda1oMzBc88Mkzc1PRDw: {
|
|
58
|
+
program: pk("extUkDFf3HLekkxbcZ3XRUizMjbxMJgKBay3p9xGVmg"),
|
|
59
|
+
tokenProgram: splToken.TOKEN_PROGRAM_ID
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
}
|
|
48
63
|
return {
|
|
49
64
|
Mainnet: {
|
|
50
65
|
mzeroXDoBpRVhnEXBra27qzAMdxgpWVY3DzQW7xMVJp: {
|
|
@@ -76,12 +91,11 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
76
91
|
}
|
|
77
92
|
}[network];
|
|
78
93
|
}
|
|
79
|
-
static getSolanaContracts(
|
|
80
|
-
const programs = _SolanaRoutes.getPrograms(
|
|
81
|
-
chainContext.network
|
|
82
|
-
);
|
|
94
|
+
static getSolanaContracts(network, chain) {
|
|
95
|
+
const programs = _SolanaRoutes.getPrograms(network);
|
|
83
96
|
const extPrograms = _SolanaRoutes.getExtPrograms(
|
|
84
|
-
|
|
97
|
+
network,
|
|
98
|
+
chain
|
|
85
99
|
);
|
|
86
100
|
return {
|
|
87
101
|
token: programs.mMint.toBase58(),
|
|
@@ -91,10 +105,19 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
91
105
|
quoter: programs.quoter.toBase58()
|
|
92
106
|
};
|
|
93
107
|
}
|
|
108
|
+
getSolanaContracts() {
|
|
109
|
+
return _SolanaRoutes.getSolanaContracts(this.network, this.ntt.chain);
|
|
110
|
+
}
|
|
94
111
|
getTransferExtensionBurnIx(amount2, recipient, payer, outboxItem, extMint, destinationToken, shouldQueue = true) {
|
|
95
|
-
const recipientAddress =
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
const recipientAddress = sdkConnect.toUniversal(
|
|
113
|
+
recipient.chain,
|
|
114
|
+
recipient.address.toString()
|
|
115
|
+
).toUint8Array();
|
|
116
|
+
if (recipientAddress.length !== 32) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`recipient address must be 32 bytes, got ${recipientAddress.length} bytes`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
98
121
|
if (destinationToken.length !== 32) {
|
|
99
122
|
throw new Error(
|
|
100
123
|
`destinationToken must be 32 bytes, got ${destinationToken.length} bytes`
|
|
@@ -107,6 +130,16 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
107
130
|
);
|
|
108
131
|
}
|
|
109
132
|
const { program: extProgram, tokenProgram: extTokenProgram } = extension;
|
|
133
|
+
const [tokenAuth] = web3_js.PublicKey.findProgramAddressSync(
|
|
134
|
+
[Buffer.from("token_authority")],
|
|
135
|
+
this.programs.portal
|
|
136
|
+
);
|
|
137
|
+
const sessionAuth = this.ntt.pdas.sessionAuthority(tokenAuth, {
|
|
138
|
+
amount: new BN__default.default(amount2),
|
|
139
|
+
recipientChain: { id: sdkConnect.chainToChainId(recipient.chain) },
|
|
140
|
+
recipientAddress: [...recipientAddress],
|
|
141
|
+
shouldQueue
|
|
142
|
+
});
|
|
110
143
|
return new web3_js.TransactionInstruction({
|
|
111
144
|
programId: this.ntt.program.programId,
|
|
112
145
|
keys: [
|
|
@@ -131,10 +164,7 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
131
164
|
// from (token auth m token account)
|
|
132
165
|
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
133
166
|
this.programs.mMint,
|
|
134
|
-
|
|
135
|
-
[Buffer.from("token_authority")],
|
|
136
|
-
this.ntt.program.programId
|
|
137
|
-
)[0],
|
|
167
|
+
tokenAuth,
|
|
138
168
|
true,
|
|
139
169
|
splToken.TOKEN_2022_PROGRAM_ID
|
|
140
170
|
),
|
|
@@ -185,24 +215,13 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
185
215
|
},
|
|
186
216
|
{
|
|
187
217
|
// session auth
|
|
188
|
-
pubkey:
|
|
189
|
-
amount: new BN__default.default(amount2),
|
|
190
|
-
recipientChain: {
|
|
191
|
-
id: 2
|
|
192
|
-
// Ethereum
|
|
193
|
-
},
|
|
194
|
-
recipientAddress: [...Array(32)],
|
|
195
|
-
shouldQueue: false
|
|
196
|
-
}),
|
|
218
|
+
pubkey: sessionAuth,
|
|
197
219
|
isSigner: false,
|
|
198
220
|
isWritable: false
|
|
199
221
|
},
|
|
200
222
|
{
|
|
201
223
|
// token auth
|
|
202
|
-
pubkey:
|
|
203
|
-
[Buffer.from("token_authority")],
|
|
204
|
-
this.ntt.program.programId
|
|
205
|
-
)[0],
|
|
224
|
+
pubkey: tokenAuth,
|
|
206
225
|
isSigner: false,
|
|
207
226
|
isWritable: false
|
|
208
227
|
},
|
|
@@ -309,10 +328,78 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
309
328
|
// chain_id
|
|
310
329
|
recipientAddress,
|
|
311
330
|
// recipient_address
|
|
312
|
-
|
|
313
|
-
// destination_token
|
|
314
|
-
Buffer.from([Number(shouldQueue)])
|
|
331
|
+
Buffer.from([Number(shouldQueue)]),
|
|
315
332
|
// should_queue
|
|
333
|
+
destinationToken
|
|
334
|
+
// destination_token
|
|
335
|
+
])
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
getExecutorRelayIx(sender, quote, destinationChain, outboxItem) {
|
|
339
|
+
const nttPeer = web3_js.PublicKey.findProgramAddressSync(
|
|
340
|
+
[
|
|
341
|
+
Buffer.from("peer"),
|
|
342
|
+
new BN__default.default(sdkConnect.chainToChainId(destinationChain)).toArrayLike(Buffer, "le", 2)
|
|
343
|
+
],
|
|
344
|
+
this.programs.portal
|
|
345
|
+
)[0];
|
|
346
|
+
const signedQuoteBytes = Buffer.from(quote.signedQuote);
|
|
347
|
+
const relayInstructions = Buffer.from(quote.relayInstructions);
|
|
348
|
+
return new web3_js.TransactionInstruction({
|
|
349
|
+
keys: [
|
|
350
|
+
{
|
|
351
|
+
pubkey: sender,
|
|
352
|
+
isSigner: true,
|
|
353
|
+
isWritable: true
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
// payee
|
|
357
|
+
pubkey: new web3_js.PublicKey(quote.payeeAddress),
|
|
358
|
+
isSigner: false,
|
|
359
|
+
isWritable: true
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
// ntt_program_id
|
|
363
|
+
pubkey: this.programs.portal,
|
|
364
|
+
isSigner: false,
|
|
365
|
+
isWritable: false
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
pubkey: nttPeer,
|
|
369
|
+
isSigner: false,
|
|
370
|
+
isWritable: false
|
|
371
|
+
},
|
|
372
|
+
{
|
|
373
|
+
// ntt_message
|
|
374
|
+
pubkey: outboxItem,
|
|
375
|
+
isSigner: false,
|
|
376
|
+
isWritable: false
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
// executor_program
|
|
380
|
+
pubkey: new web3_js.PublicKey("execXUrAsMnqMmTHj5m7N1YQgsDz3cwGLYCYyuDRciV"),
|
|
381
|
+
isSigner: false,
|
|
382
|
+
isWritable: false
|
|
383
|
+
},
|
|
384
|
+
{
|
|
385
|
+
pubkey: web3_js.SystemProgram.programId,
|
|
386
|
+
isSigner: false,
|
|
387
|
+
isWritable: false
|
|
388
|
+
}
|
|
389
|
+
],
|
|
390
|
+
programId: new web3_js.PublicKey("nex1gkSWtRBheEJuQZMqHhbMG5A45qPU76KqnCZNVHR"),
|
|
391
|
+
data: Buffer.concat([
|
|
392
|
+
Buffer.from(sha2.sha256("global:relay_ntt_mesage").subarray(0, 8)),
|
|
393
|
+
new BN__default.default(sdkConnect.chainToChainId(destinationChain)).toArrayLike(Buffer, "le", 2),
|
|
394
|
+
// recipient_chain
|
|
395
|
+
new BN__default.default(signedQuoteBytes.length).toArrayLike(Buffer, "le", 4),
|
|
396
|
+
// vec length
|
|
397
|
+
Buffer.from(signedQuoteBytes),
|
|
398
|
+
// signed_quote_bytes
|
|
399
|
+
new BN__default.default(relayInstructions.length).toArrayLike(Buffer, "le", 4),
|
|
400
|
+
// vec length
|
|
401
|
+
Buffer.from(relayInstructions)
|
|
402
|
+
// relay_instructions
|
|
316
403
|
])
|
|
317
404
|
});
|
|
318
405
|
}
|
|
@@ -577,6 +664,62 @@ function pk(address) {
|
|
|
577
664
|
return new web3_js.PublicKey(address);
|
|
578
665
|
}
|
|
579
666
|
|
|
667
|
+
// src/executor.ts
|
|
668
|
+
function getExecutorConfig(network = "Mainnet") {
|
|
669
|
+
const svmContracts = SolanaRoutes.getSolanaContracts(network, "Solana");
|
|
670
|
+
const svmChains = ["Solana", "Fogo"];
|
|
671
|
+
const evmChains = network === "Mainnet" ? ["Ethereum", "Optimism", "Arbitrum"] : ["Sepolia", "ArbitrumSepolia", "OptimismSepolia"];
|
|
672
|
+
return {
|
|
673
|
+
ntt: {
|
|
674
|
+
tokens: {
|
|
675
|
+
M0: [
|
|
676
|
+
...svmChains.map((chain) => ({
|
|
677
|
+
chain,
|
|
678
|
+
token: svmContracts.token,
|
|
679
|
+
manager: svmContracts.manager,
|
|
680
|
+
transceiver: [
|
|
681
|
+
{
|
|
682
|
+
type: "wormhole",
|
|
683
|
+
address: svmContracts.transceiver.wormhole
|
|
684
|
+
}
|
|
685
|
+
],
|
|
686
|
+
quoter: svmContracts.quoter
|
|
687
|
+
})),
|
|
688
|
+
...evmChains.map((chain) => ({
|
|
689
|
+
chain,
|
|
690
|
+
token: M0AutomaticRoute.EVM_CONTRACTS.token,
|
|
691
|
+
manager: M0AutomaticRoute.EVM_CONTRACTS.manager,
|
|
692
|
+
transceiver: [
|
|
693
|
+
{
|
|
694
|
+
type: "wormhole",
|
|
695
|
+
address: M0AutomaticRoute.EVM_CONTRACTS.transceiver.wormhole
|
|
696
|
+
}
|
|
697
|
+
],
|
|
698
|
+
quoter: M0AutomaticRoute.EVM_CONTRACTS.quoter
|
|
699
|
+
}))
|
|
700
|
+
]
|
|
701
|
+
}
|
|
702
|
+
},
|
|
703
|
+
referrerFee: {
|
|
704
|
+
feeDbps: 0n,
|
|
705
|
+
perTokenOverrides: {
|
|
706
|
+
// SVM chains require extra compute when receiving messages
|
|
707
|
+
// so we need to override the gas cost
|
|
708
|
+
Solana: {
|
|
709
|
+
[svmContracts.token]: {
|
|
710
|
+
msgValue: 15000000n
|
|
711
|
+
}
|
|
712
|
+
},
|
|
713
|
+
Fogo: {
|
|
714
|
+
[svmContracts.token]: {
|
|
715
|
+
msgValue: 15000000n
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
|
|
580
723
|
// src/m0AutomaticRoute.ts
|
|
581
724
|
var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.AutomaticRoute {
|
|
582
725
|
static supportedNetworks() {
|
|
@@ -604,21 +747,18 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
604
747
|
static getContracts(chainContext) {
|
|
605
748
|
switch (chainContext.chain) {
|
|
606
749
|
case "Ethereum":
|
|
607
|
-
return this.EVM_CONTRACTS;
|
|
608
750
|
case "Optimism":
|
|
609
|
-
return this.EVM_CONTRACTS;
|
|
610
751
|
case "Arbitrum":
|
|
611
|
-
return this.EVM_CONTRACTS;
|
|
612
752
|
case "Sepolia":
|
|
613
|
-
return this.EVM_CONTRACTS;
|
|
614
753
|
case "OptimismSepolia":
|
|
615
|
-
return this.EVM_CONTRACTS;
|
|
616
754
|
case "ArbitrumSepolia":
|
|
617
755
|
return this.EVM_CONTRACTS;
|
|
618
756
|
case "Solana":
|
|
619
|
-
return SolanaRoutes.getSolanaContracts(chainContext);
|
|
620
757
|
case "Fogo":
|
|
621
|
-
return SolanaRoutes.getSolanaContracts(
|
|
758
|
+
return SolanaRoutes.getSolanaContracts(
|
|
759
|
+
chainContext.network,
|
|
760
|
+
chainContext.chain
|
|
761
|
+
);
|
|
622
762
|
default:
|
|
623
763
|
throw new Error(`Unsupported chain: ${chainContext.chain}`);
|
|
624
764
|
}
|
|
@@ -636,9 +776,11 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
636
776
|
return [];
|
|
637
777
|
}
|
|
638
778
|
const { token: mToken, mLikeTokens } = this.getContracts(toChain);
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
779
|
+
const tokens = mLikeTokens.map((x) => sdkConnect.Wormhole.tokenId(toChain.chain, x));
|
|
780
|
+
if (toChain.chain === "Solana" || toChain.chain === "Fogo") {
|
|
781
|
+
return tokens;
|
|
782
|
+
}
|
|
783
|
+
return [...tokens, sdkConnect.Wormhole.tokenId(toChain.chain, mToken)];
|
|
642
784
|
}
|
|
643
785
|
static isProtocolSupported(chain) {
|
|
644
786
|
return chain.supportsProtocol("Ntt");
|
|
@@ -654,10 +796,6 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
654
796
|
}
|
|
655
797
|
async validate(request, params) {
|
|
656
798
|
const options = params.options ?? this.getDefaultOptions();
|
|
657
|
-
const gasDropoff = sdkConnect.amount.parse(
|
|
658
|
-
options.gasDropoff ?? "0.0",
|
|
659
|
-
request.toChain.config.nativeTokenDecimals
|
|
660
|
-
);
|
|
661
799
|
const parsedAmount = sdkConnect.amount.parse(params.amount, request.source.decimals);
|
|
662
800
|
const trimmedAmount = sdkRouteNtt.NttRoute.trimAmount(
|
|
663
801
|
parsedAmount,
|
|
@@ -673,8 +811,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
673
811
|
destinationContracts: toContracts,
|
|
674
812
|
options: {
|
|
675
813
|
queue: false,
|
|
676
|
-
automatic: true
|
|
677
|
-
gasDropoff: sdkConnect.amount.units(gasDropoff)
|
|
814
|
+
automatic: true
|
|
678
815
|
}
|
|
679
816
|
},
|
|
680
817
|
options
|
|
@@ -719,7 +856,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
719
856
|
)
|
|
720
857
|
},
|
|
721
858
|
destinationNativeGas: sdkConnect.amount.fromBaseUnits(
|
|
722
|
-
|
|
859
|
+
0n,
|
|
723
860
|
toChain.config.nativeTokenDecimals
|
|
724
861
|
),
|
|
725
862
|
eta: sdkConnect.finality.estimateFinalityTime(request.fromChain.chain)
|
|
@@ -780,18 +917,18 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
780
917
|
*/
|
|
781
918
|
async *transferMLike(ntt, sender, amount2, destination, sourceToken, destinationToken, options) {
|
|
782
919
|
const senderAddress = new sdkEvm.EvmAddress(sender).toString();
|
|
783
|
-
const totalPrice = await ntt.quoteDeliveryPrice(destination.chain, options);
|
|
784
920
|
const tokenContract = sdkEvm.EvmPlatform.getTokenImplementation(
|
|
785
921
|
ntt.provider,
|
|
786
922
|
sourceToken
|
|
787
923
|
);
|
|
924
|
+
const spenderAddress = this.requiresExecutor(destination.chain) ? _M0AutomaticRoute.EXECUTOR_ENTRYPOINT : ntt.managerAddress;
|
|
788
925
|
const allowance = await tokenContract.allowance(
|
|
789
926
|
senderAddress,
|
|
790
|
-
|
|
927
|
+
spenderAddress
|
|
791
928
|
);
|
|
792
929
|
if (allowance < amount2) {
|
|
793
930
|
const txReq2 = await tokenContract.approve.populateTransaction(
|
|
794
|
-
|
|
931
|
+
spenderAddress,
|
|
795
932
|
amount2
|
|
796
933
|
);
|
|
797
934
|
yield this.createUnsignedTx(
|
|
@@ -801,6 +938,36 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
801
938
|
);
|
|
802
939
|
}
|
|
803
940
|
const receiver = sdkConnect.universalAddress(destination);
|
|
941
|
+
if (this.requiresExecutor(destination.chain)) {
|
|
942
|
+
const quote = await this.getExecutorQuote(
|
|
943
|
+
ntt.network,
|
|
944
|
+
ntt.chain,
|
|
945
|
+
destination.chain,
|
|
946
|
+
amount2
|
|
947
|
+
);
|
|
948
|
+
const contract2 = new ethers.Contract(_M0AutomaticRoute.EXECUTOR_ENTRYPOINT, [
|
|
949
|
+
"function transferMLikeToken(uint256 amount, address sourceToken, uint16 destinationChainId, bytes32 destinationToken, bytes32 recipient, bytes32 refundAddress, (uint256 value, address refundAddress, bytes signedQuote, bytes instructions) executorArgs, bytes memory transceiverInstructions) external payable returns (bytes32 messageId)"
|
|
950
|
+
]);
|
|
951
|
+
const executorArgs = {
|
|
952
|
+
value: quote.estimatedCost,
|
|
953
|
+
refundAddress: senderAddress,
|
|
954
|
+
signedQuote: quote.signedQuote,
|
|
955
|
+
instructions: quote.relayInstructions
|
|
956
|
+
};
|
|
957
|
+
const txReq2 = await contract2.getFunction("transferMLikeToken").populateTransaction(
|
|
958
|
+
amount2,
|
|
959
|
+
sourceToken,
|
|
960
|
+
sdkConnect.toChainId(destination.chain),
|
|
961
|
+
sdkConnect.toUniversal(destination.chain, destinationToken).toString(),
|
|
962
|
+
receiver,
|
|
963
|
+
receiver,
|
|
964
|
+
executorArgs,
|
|
965
|
+
Uint8Array.from(Buffer.from("01000101", "hex")),
|
|
966
|
+
{ value: quote.estimatedCost }
|
|
967
|
+
);
|
|
968
|
+
yield ntt.createUnsignedTx(sdkEvm.addFrom(txReq2, senderAddress), "Ntt.transfer");
|
|
969
|
+
return;
|
|
970
|
+
}
|
|
804
971
|
const contract = new ethers.Contract(ntt.managerAddress, [
|
|
805
972
|
"function transferMLikeToken(uint256 amount, address sourceToken, uint16 destinationChainId, bytes32 destinationToken, bytes32 recipient, bytes32 refundAddress) external payable returns (uint64 sequence)"
|
|
806
973
|
]);
|
|
@@ -811,7 +978,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
811
978
|
sdkConnect.toUniversal(destination.chain, destinationToken).toString(),
|
|
812
979
|
receiver,
|
|
813
980
|
receiver,
|
|
814
|
-
{ value:
|
|
981
|
+
{ value: await ntt.quoteDeliveryPrice(destination.chain, options) }
|
|
815
982
|
);
|
|
816
983
|
yield ntt.createUnsignedTx(sdkEvm.addFrom(txReq, senderAddress), "Ntt.transfer");
|
|
817
984
|
}
|
|
@@ -826,7 +993,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
826
993
|
}
|
|
827
994
|
async *transferSolanaExtension(ntt, sender, amount2, recipient, sourceToken, destinationToken, options, outboxItem) {
|
|
828
995
|
const router = new SolanaRoutes(ntt);
|
|
829
|
-
if (
|
|
996
|
+
if (router.getSolanaContracts().token === sourceToken) {
|
|
830
997
|
return ntt.transfer(sender, amount2, recipient, options);
|
|
831
998
|
}
|
|
832
999
|
const config = await ntt.getConfig();
|
|
@@ -861,18 +1028,34 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
861
1028
|
const tx = new web3_js.Transaction();
|
|
862
1029
|
tx.feePayer = payerAddress;
|
|
863
1030
|
tx.add(...ixs);
|
|
864
|
-
if (
|
|
865
|
-
|
|
1031
|
+
if (this.requiresExecutor(recipient.chain)) {
|
|
1032
|
+
const quote = await this.getExecutorQuote(
|
|
1033
|
+
ntt.network,
|
|
1034
|
+
ntt.chain,
|
|
1035
|
+
recipient.chain,
|
|
1036
|
+
amount2
|
|
1037
|
+
);
|
|
1038
|
+
tx.add(
|
|
1039
|
+
router.getExecutorRelayIx(
|
|
1040
|
+
payerAddress,
|
|
1041
|
+
quote,
|
|
1042
|
+
recipient.chain,
|
|
1043
|
+
outboxItem.publicKey
|
|
1044
|
+
)
|
|
1045
|
+
);
|
|
1046
|
+
} else if (options.automatic) {
|
|
1047
|
+
if (!ntt.quoter) {
|
|
866
1048
|
throw new Error(
|
|
867
1049
|
"No quoter available, cannot initiate an automatic transfer."
|
|
868
1050
|
);
|
|
1051
|
+
}
|
|
869
1052
|
const fee = await ntt.quoteDeliveryPrice(recipient.chain, options);
|
|
870
1053
|
const relayIx = await ntt.quoter.createRequestRelayInstruction(
|
|
871
1054
|
payerAddress,
|
|
872
1055
|
outboxItem.publicKey,
|
|
873
1056
|
recipient.chain,
|
|
874
1057
|
Number(fee) / web3_js.LAMPORTS_PER_SOL,
|
|
875
|
-
|
|
1058
|
+
0
|
|
876
1059
|
);
|
|
877
1060
|
tx.add(relayIx);
|
|
878
1061
|
}
|
|
@@ -952,11 +1135,44 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
952
1135
|
}
|
|
953
1136
|
yield receipt;
|
|
954
1137
|
}
|
|
1138
|
+
async getExecutorQuote(network, sourceChain, destinationChain, amount2) {
|
|
1139
|
+
const wh = new sdkConnect.Wormhole(network, [solana__default.default.Platform, evm__default.default.Platform]);
|
|
1140
|
+
const executorRoute = sdkRouteNtt.nttExecutorRoute(getExecutorConfig(network));
|
|
1141
|
+
const routeInstance = new executorRoute(wh);
|
|
1142
|
+
const resolveM = (chain) => {
|
|
1143
|
+
if (sdkConnect.chainToPlatform(chain) === "Solana") {
|
|
1144
|
+
const c = chain;
|
|
1145
|
+
return SolanaRoutes.getSolanaContracts(network, c).token;
|
|
1146
|
+
}
|
|
1147
|
+
return _M0AutomaticRoute.EVM_CONTRACTS.token;
|
|
1148
|
+
};
|
|
1149
|
+
const transferRequest = await sdkConnect.routes.RouteTransferRequest.create(wh, {
|
|
1150
|
+
source: sdkConnect.Wormhole.tokenId(sourceChain, resolveM(sourceChain)),
|
|
1151
|
+
destination: sdkConnect.Wormhole.tokenId(
|
|
1152
|
+
destinationChain,
|
|
1153
|
+
resolveM(destinationChain)
|
|
1154
|
+
)
|
|
1155
|
+
});
|
|
1156
|
+
const validated = await routeInstance.validate(transferRequest, {
|
|
1157
|
+
amount: amount2.toString()
|
|
1158
|
+
});
|
|
1159
|
+
if (!validated.valid) {
|
|
1160
|
+
throw new Error(`Validation failed: ${validated.error.message}`);
|
|
1161
|
+
}
|
|
1162
|
+
return await routeInstance.fetchExecutorQuote(
|
|
1163
|
+
transferRequest,
|
|
1164
|
+
validated.params
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1167
|
+
requiresExecutor(destination) {
|
|
1168
|
+
return sdkConnect.chainToPlatform(destination) === "Solana";
|
|
1169
|
+
}
|
|
955
1170
|
};
|
|
956
1171
|
// ntt does not support gas drop-off currently
|
|
957
1172
|
_M0AutomaticRoute.NATIVE_GAS_DROPOFF_SUPPORTED = false;
|
|
958
1173
|
// Wrapped M token address is the same on EVM chains
|
|
959
1174
|
_M0AutomaticRoute.EVM_WRAPPED_M_TOKEN = "0x437cc33344a0B27A429f795ff6B469C72698B291";
|
|
1175
|
+
_M0AutomaticRoute.EXECUTOR_ENTRYPOINT = "0x8518040a9cf9dfb55a4f099bb0eaabeefeb03643";
|
|
960
1176
|
// Contract addresses are the same on all EVM chains
|
|
961
1177
|
_M0AutomaticRoute.EVM_CONTRACTS = {
|
|
962
1178
|
// M token address is the same on EVM chains
|
package/dist/index.mjs
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { routes, Wormhole, isSameToken, amount, finality, chainToPlatform, canonicalAddress, signSendWait, TransferState, universalAddress, toChainId, toUniversal, isSourceInitiated, isSourceFinalized, isAttested, isRedeemed, chainToChainId } from '@wormhole-foundation/sdk-connect';
|
|
2
2
|
import { Ntt } from '@wormhole-foundation/sdk-definitions-ntt';
|
|
3
|
-
import { WEI_PER_GWEI, NTT } from '@wormhole-foundation/sdk-solana-ntt';
|
|
4
3
|
import { EvmAddress, EvmPlatform, addFrom, EvmUnsignedTransaction, addChainId } from '@wormhole-foundation/sdk-evm';
|
|
5
4
|
import { SolanaAddress } from '@wormhole-foundation/sdk-solana';
|
|
6
|
-
import { NttRoute } from '@wormhole-foundation/sdk-route-ntt';
|
|
5
|
+
import { NttRoute, nttExecutorRoute } from '@wormhole-foundation/sdk-route-ntt';
|
|
7
6
|
import { Contract } from 'ethers';
|
|
8
7
|
import { Keypair, PublicKey, Transaction, LAMPORTS_PER_SOL, TransactionMessage, VersionedTransaction, TransactionInstruction, SystemProgram, AddressLookupTableAccount } from '@solana/web3.js';
|
|
9
|
-
import { TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync, createAssociatedTokenAccountInstruction } from '@solana/spl-token';
|
|
8
|
+
import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, getAssociatedTokenAddressSync, createAssociatedTokenAccountInstruction } from '@solana/spl-token';
|
|
9
|
+
import { NTT } from '@wormhole-foundation/sdk-solana-ntt';
|
|
10
10
|
import BN from 'bn.js';
|
|
11
11
|
import { sha256 } from '@noble/hashes/sha2';
|
|
12
|
+
import evm from '@wormhole-foundation/sdk/platforms/evm';
|
|
13
|
+
import solana from '@wormhole-foundation/sdk/platforms/solana';
|
|
12
14
|
|
|
13
15
|
// src/m0AutomaticRoute.ts
|
|
14
16
|
var SolanaRoutes = class _SolanaRoutes {
|
|
@@ -16,7 +18,10 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
16
18
|
this.ntt = ntt;
|
|
17
19
|
this.network = ntt.network;
|
|
18
20
|
this.programs = _SolanaRoutes.getPrograms(this.network);
|
|
19
|
-
this.extPrograms = _SolanaRoutes.getExtPrograms(
|
|
21
|
+
this.extPrograms = _SolanaRoutes.getExtPrograms(
|
|
22
|
+
this.network,
|
|
23
|
+
this.ntt.chain
|
|
24
|
+
);
|
|
20
25
|
}
|
|
21
26
|
static getPrograms(network) {
|
|
22
27
|
return {
|
|
@@ -24,7 +29,7 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
24
29
|
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
25
30
|
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
26
31
|
lut: pk("9JLRqBqkznKiSoNfotA4ywSRdnWb2fE76SiFrAfkaRCD"),
|
|
27
|
-
mMint: pk("
|
|
32
|
+
mMint: pk("mzerojk9tg56ebsrEAhfkyc9VgKjTW2zDqp6C5mhjzH"),
|
|
28
33
|
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
29
34
|
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
30
35
|
},
|
|
@@ -32,13 +37,21 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
32
37
|
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
33
38
|
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
34
39
|
lut: pk("6GhuWPuAmiJeeSVsr58KjqHcAejJRndCx9BVtHkaYHUR"),
|
|
35
|
-
mMint: pk("
|
|
40
|
+
mMint: pk("mzerojk9tg56ebsrEAhfkyc9VgKjTW2zDqp6C5mhjzH"),
|
|
36
41
|
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
37
42
|
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
38
43
|
}
|
|
39
44
|
}[network];
|
|
40
45
|
}
|
|
41
|
-
static getExtPrograms(network) {
|
|
46
|
+
static getExtPrograms(network, chain) {
|
|
47
|
+
if (chain === "Fogo") {
|
|
48
|
+
return {
|
|
49
|
+
fUSDqquEMUU8UmU2YWYGZy2Lda1oMzBc88Mkzc1PRDw: {
|
|
50
|
+
program: pk("extUkDFf3HLekkxbcZ3XRUizMjbxMJgKBay3p9xGVmg"),
|
|
51
|
+
tokenProgram: TOKEN_PROGRAM_ID
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
42
55
|
return {
|
|
43
56
|
Mainnet: {
|
|
44
57
|
mzeroXDoBpRVhnEXBra27qzAMdxgpWVY3DzQW7xMVJp: {
|
|
@@ -70,12 +83,11 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
70
83
|
}
|
|
71
84
|
}[network];
|
|
72
85
|
}
|
|
73
|
-
static getSolanaContracts(
|
|
74
|
-
const programs = _SolanaRoutes.getPrograms(
|
|
75
|
-
chainContext.network
|
|
76
|
-
);
|
|
86
|
+
static getSolanaContracts(network, chain) {
|
|
87
|
+
const programs = _SolanaRoutes.getPrograms(network);
|
|
77
88
|
const extPrograms = _SolanaRoutes.getExtPrograms(
|
|
78
|
-
|
|
89
|
+
network,
|
|
90
|
+
chain
|
|
79
91
|
);
|
|
80
92
|
return {
|
|
81
93
|
token: programs.mMint.toBase58(),
|
|
@@ -85,10 +97,19 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
85
97
|
quoter: programs.quoter.toBase58()
|
|
86
98
|
};
|
|
87
99
|
}
|
|
100
|
+
getSolanaContracts() {
|
|
101
|
+
return _SolanaRoutes.getSolanaContracts(this.network, this.ntt.chain);
|
|
102
|
+
}
|
|
88
103
|
getTransferExtensionBurnIx(amount2, recipient, payer, outboxItem, extMint, destinationToken, shouldQueue = true) {
|
|
89
|
-
const recipientAddress =
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
const recipientAddress = toUniversal(
|
|
105
|
+
recipient.chain,
|
|
106
|
+
recipient.address.toString()
|
|
107
|
+
).toUint8Array();
|
|
108
|
+
if (recipientAddress.length !== 32) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`recipient address must be 32 bytes, got ${recipientAddress.length} bytes`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
92
113
|
if (destinationToken.length !== 32) {
|
|
93
114
|
throw new Error(
|
|
94
115
|
`destinationToken must be 32 bytes, got ${destinationToken.length} bytes`
|
|
@@ -101,6 +122,16 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
101
122
|
);
|
|
102
123
|
}
|
|
103
124
|
const { program: extProgram, tokenProgram: extTokenProgram } = extension;
|
|
125
|
+
const [tokenAuth] = PublicKey.findProgramAddressSync(
|
|
126
|
+
[Buffer.from("token_authority")],
|
|
127
|
+
this.programs.portal
|
|
128
|
+
);
|
|
129
|
+
const sessionAuth = this.ntt.pdas.sessionAuthority(tokenAuth, {
|
|
130
|
+
amount: new BN(amount2),
|
|
131
|
+
recipientChain: { id: chainToChainId(recipient.chain) },
|
|
132
|
+
recipientAddress: [...recipientAddress],
|
|
133
|
+
shouldQueue
|
|
134
|
+
});
|
|
104
135
|
return new TransactionInstruction({
|
|
105
136
|
programId: this.ntt.program.programId,
|
|
106
137
|
keys: [
|
|
@@ -125,10 +156,7 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
125
156
|
// from (token auth m token account)
|
|
126
157
|
pubkey: getAssociatedTokenAddressSync(
|
|
127
158
|
this.programs.mMint,
|
|
128
|
-
|
|
129
|
-
[Buffer.from("token_authority")],
|
|
130
|
-
this.ntt.program.programId
|
|
131
|
-
)[0],
|
|
159
|
+
tokenAuth,
|
|
132
160
|
true,
|
|
133
161
|
TOKEN_2022_PROGRAM_ID
|
|
134
162
|
),
|
|
@@ -179,24 +207,13 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
179
207
|
},
|
|
180
208
|
{
|
|
181
209
|
// session auth
|
|
182
|
-
pubkey:
|
|
183
|
-
amount: new BN(amount2),
|
|
184
|
-
recipientChain: {
|
|
185
|
-
id: 2
|
|
186
|
-
// Ethereum
|
|
187
|
-
},
|
|
188
|
-
recipientAddress: [...Array(32)],
|
|
189
|
-
shouldQueue: false
|
|
190
|
-
}),
|
|
210
|
+
pubkey: sessionAuth,
|
|
191
211
|
isSigner: false,
|
|
192
212
|
isWritable: false
|
|
193
213
|
},
|
|
194
214
|
{
|
|
195
215
|
// token auth
|
|
196
|
-
pubkey:
|
|
197
|
-
[Buffer.from("token_authority")],
|
|
198
|
-
this.ntt.program.programId
|
|
199
|
-
)[0],
|
|
216
|
+
pubkey: tokenAuth,
|
|
200
217
|
isSigner: false,
|
|
201
218
|
isWritable: false
|
|
202
219
|
},
|
|
@@ -303,10 +320,78 @@ var SolanaRoutes = class _SolanaRoutes {
|
|
|
303
320
|
// chain_id
|
|
304
321
|
recipientAddress,
|
|
305
322
|
// recipient_address
|
|
306
|
-
|
|
307
|
-
// destination_token
|
|
308
|
-
Buffer.from([Number(shouldQueue)])
|
|
323
|
+
Buffer.from([Number(shouldQueue)]),
|
|
309
324
|
// should_queue
|
|
325
|
+
destinationToken
|
|
326
|
+
// destination_token
|
|
327
|
+
])
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
getExecutorRelayIx(sender, quote, destinationChain, outboxItem) {
|
|
331
|
+
const nttPeer = PublicKey.findProgramAddressSync(
|
|
332
|
+
[
|
|
333
|
+
Buffer.from("peer"),
|
|
334
|
+
new BN(chainToChainId(destinationChain)).toArrayLike(Buffer, "le", 2)
|
|
335
|
+
],
|
|
336
|
+
this.programs.portal
|
|
337
|
+
)[0];
|
|
338
|
+
const signedQuoteBytes = Buffer.from(quote.signedQuote);
|
|
339
|
+
const relayInstructions = Buffer.from(quote.relayInstructions);
|
|
340
|
+
return new TransactionInstruction({
|
|
341
|
+
keys: [
|
|
342
|
+
{
|
|
343
|
+
pubkey: sender,
|
|
344
|
+
isSigner: true,
|
|
345
|
+
isWritable: true
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
// payee
|
|
349
|
+
pubkey: new PublicKey(quote.payeeAddress),
|
|
350
|
+
isSigner: false,
|
|
351
|
+
isWritable: true
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
// ntt_program_id
|
|
355
|
+
pubkey: this.programs.portal,
|
|
356
|
+
isSigner: false,
|
|
357
|
+
isWritable: false
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
pubkey: nttPeer,
|
|
361
|
+
isSigner: false,
|
|
362
|
+
isWritable: false
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
// ntt_message
|
|
366
|
+
pubkey: outboxItem,
|
|
367
|
+
isSigner: false,
|
|
368
|
+
isWritable: false
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
// executor_program
|
|
372
|
+
pubkey: new PublicKey("execXUrAsMnqMmTHj5m7N1YQgsDz3cwGLYCYyuDRciV"),
|
|
373
|
+
isSigner: false,
|
|
374
|
+
isWritable: false
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
pubkey: SystemProgram.programId,
|
|
378
|
+
isSigner: false,
|
|
379
|
+
isWritable: false
|
|
380
|
+
}
|
|
381
|
+
],
|
|
382
|
+
programId: new PublicKey("nex1gkSWtRBheEJuQZMqHhbMG5A45qPU76KqnCZNVHR"),
|
|
383
|
+
data: Buffer.concat([
|
|
384
|
+
Buffer.from(sha256("global:relay_ntt_mesage").subarray(0, 8)),
|
|
385
|
+
new BN(chainToChainId(destinationChain)).toArrayLike(Buffer, "le", 2),
|
|
386
|
+
// recipient_chain
|
|
387
|
+
new BN(signedQuoteBytes.length).toArrayLike(Buffer, "le", 4),
|
|
388
|
+
// vec length
|
|
389
|
+
Buffer.from(signedQuoteBytes),
|
|
390
|
+
// signed_quote_bytes
|
|
391
|
+
new BN(relayInstructions.length).toArrayLike(Buffer, "le", 4),
|
|
392
|
+
// vec length
|
|
393
|
+
Buffer.from(relayInstructions)
|
|
394
|
+
// relay_instructions
|
|
310
395
|
])
|
|
311
396
|
});
|
|
312
397
|
}
|
|
@@ -571,6 +656,62 @@ function pk(address) {
|
|
|
571
656
|
return new PublicKey(address);
|
|
572
657
|
}
|
|
573
658
|
|
|
659
|
+
// src/executor.ts
|
|
660
|
+
function getExecutorConfig(network = "Mainnet") {
|
|
661
|
+
const svmContracts = SolanaRoutes.getSolanaContracts(network, "Solana");
|
|
662
|
+
const svmChains = ["Solana", "Fogo"];
|
|
663
|
+
const evmChains = network === "Mainnet" ? ["Ethereum", "Optimism", "Arbitrum"] : ["Sepolia", "ArbitrumSepolia", "OptimismSepolia"];
|
|
664
|
+
return {
|
|
665
|
+
ntt: {
|
|
666
|
+
tokens: {
|
|
667
|
+
M0: [
|
|
668
|
+
...svmChains.map((chain) => ({
|
|
669
|
+
chain,
|
|
670
|
+
token: svmContracts.token,
|
|
671
|
+
manager: svmContracts.manager,
|
|
672
|
+
transceiver: [
|
|
673
|
+
{
|
|
674
|
+
type: "wormhole",
|
|
675
|
+
address: svmContracts.transceiver.wormhole
|
|
676
|
+
}
|
|
677
|
+
],
|
|
678
|
+
quoter: svmContracts.quoter
|
|
679
|
+
})),
|
|
680
|
+
...evmChains.map((chain) => ({
|
|
681
|
+
chain,
|
|
682
|
+
token: M0AutomaticRoute.EVM_CONTRACTS.token,
|
|
683
|
+
manager: M0AutomaticRoute.EVM_CONTRACTS.manager,
|
|
684
|
+
transceiver: [
|
|
685
|
+
{
|
|
686
|
+
type: "wormhole",
|
|
687
|
+
address: M0AutomaticRoute.EVM_CONTRACTS.transceiver.wormhole
|
|
688
|
+
}
|
|
689
|
+
],
|
|
690
|
+
quoter: M0AutomaticRoute.EVM_CONTRACTS.quoter
|
|
691
|
+
}))
|
|
692
|
+
]
|
|
693
|
+
}
|
|
694
|
+
},
|
|
695
|
+
referrerFee: {
|
|
696
|
+
feeDbps: 0n,
|
|
697
|
+
perTokenOverrides: {
|
|
698
|
+
// SVM chains require extra compute when receiving messages
|
|
699
|
+
// so we need to override the gas cost
|
|
700
|
+
Solana: {
|
|
701
|
+
[svmContracts.token]: {
|
|
702
|
+
msgValue: 15000000n
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
Fogo: {
|
|
706
|
+
[svmContracts.token]: {
|
|
707
|
+
msgValue: 15000000n
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
574
715
|
// src/m0AutomaticRoute.ts
|
|
575
716
|
var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
576
717
|
static supportedNetworks() {
|
|
@@ -598,21 +739,18 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
598
739
|
static getContracts(chainContext) {
|
|
599
740
|
switch (chainContext.chain) {
|
|
600
741
|
case "Ethereum":
|
|
601
|
-
return this.EVM_CONTRACTS;
|
|
602
742
|
case "Optimism":
|
|
603
|
-
return this.EVM_CONTRACTS;
|
|
604
743
|
case "Arbitrum":
|
|
605
|
-
return this.EVM_CONTRACTS;
|
|
606
744
|
case "Sepolia":
|
|
607
|
-
return this.EVM_CONTRACTS;
|
|
608
745
|
case "OptimismSepolia":
|
|
609
|
-
return this.EVM_CONTRACTS;
|
|
610
746
|
case "ArbitrumSepolia":
|
|
611
747
|
return this.EVM_CONTRACTS;
|
|
612
748
|
case "Solana":
|
|
613
|
-
return SolanaRoutes.getSolanaContracts(chainContext);
|
|
614
749
|
case "Fogo":
|
|
615
|
-
return SolanaRoutes.getSolanaContracts(
|
|
750
|
+
return SolanaRoutes.getSolanaContracts(
|
|
751
|
+
chainContext.network,
|
|
752
|
+
chainContext.chain
|
|
753
|
+
);
|
|
616
754
|
default:
|
|
617
755
|
throw new Error(`Unsupported chain: ${chainContext.chain}`);
|
|
618
756
|
}
|
|
@@ -630,9 +768,11 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
630
768
|
return [];
|
|
631
769
|
}
|
|
632
770
|
const { token: mToken, mLikeTokens } = this.getContracts(toChain);
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
771
|
+
const tokens = mLikeTokens.map((x) => Wormhole.tokenId(toChain.chain, x));
|
|
772
|
+
if (toChain.chain === "Solana" || toChain.chain === "Fogo") {
|
|
773
|
+
return tokens;
|
|
774
|
+
}
|
|
775
|
+
return [...tokens, Wormhole.tokenId(toChain.chain, mToken)];
|
|
636
776
|
}
|
|
637
777
|
static isProtocolSupported(chain) {
|
|
638
778
|
return chain.supportsProtocol("Ntt");
|
|
@@ -648,10 +788,6 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
648
788
|
}
|
|
649
789
|
async validate(request, params) {
|
|
650
790
|
const options = params.options ?? this.getDefaultOptions();
|
|
651
|
-
const gasDropoff = amount.parse(
|
|
652
|
-
options.gasDropoff ?? "0.0",
|
|
653
|
-
request.toChain.config.nativeTokenDecimals
|
|
654
|
-
);
|
|
655
791
|
const parsedAmount = amount.parse(params.amount, request.source.decimals);
|
|
656
792
|
const trimmedAmount = NttRoute.trimAmount(
|
|
657
793
|
parsedAmount,
|
|
@@ -667,8 +803,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
667
803
|
destinationContracts: toContracts,
|
|
668
804
|
options: {
|
|
669
805
|
queue: false,
|
|
670
|
-
automatic: true
|
|
671
|
-
gasDropoff: amount.units(gasDropoff)
|
|
806
|
+
automatic: true
|
|
672
807
|
}
|
|
673
808
|
},
|
|
674
809
|
options
|
|
@@ -713,7 +848,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
713
848
|
)
|
|
714
849
|
},
|
|
715
850
|
destinationNativeGas: amount.fromBaseUnits(
|
|
716
|
-
|
|
851
|
+
0n,
|
|
717
852
|
toChain.config.nativeTokenDecimals
|
|
718
853
|
),
|
|
719
854
|
eta: finality.estimateFinalityTime(request.fromChain.chain)
|
|
@@ -774,18 +909,18 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
774
909
|
*/
|
|
775
910
|
async *transferMLike(ntt, sender, amount2, destination, sourceToken, destinationToken, options) {
|
|
776
911
|
const senderAddress = new EvmAddress(sender).toString();
|
|
777
|
-
const totalPrice = await ntt.quoteDeliveryPrice(destination.chain, options);
|
|
778
912
|
const tokenContract = EvmPlatform.getTokenImplementation(
|
|
779
913
|
ntt.provider,
|
|
780
914
|
sourceToken
|
|
781
915
|
);
|
|
916
|
+
const spenderAddress = this.requiresExecutor(destination.chain) ? _M0AutomaticRoute.EXECUTOR_ENTRYPOINT : ntt.managerAddress;
|
|
782
917
|
const allowance = await tokenContract.allowance(
|
|
783
918
|
senderAddress,
|
|
784
|
-
|
|
919
|
+
spenderAddress
|
|
785
920
|
);
|
|
786
921
|
if (allowance < amount2) {
|
|
787
922
|
const txReq2 = await tokenContract.approve.populateTransaction(
|
|
788
|
-
|
|
923
|
+
spenderAddress,
|
|
789
924
|
amount2
|
|
790
925
|
);
|
|
791
926
|
yield this.createUnsignedTx(
|
|
@@ -795,6 +930,36 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
795
930
|
);
|
|
796
931
|
}
|
|
797
932
|
const receiver = universalAddress(destination);
|
|
933
|
+
if (this.requiresExecutor(destination.chain)) {
|
|
934
|
+
const quote = await this.getExecutorQuote(
|
|
935
|
+
ntt.network,
|
|
936
|
+
ntt.chain,
|
|
937
|
+
destination.chain,
|
|
938
|
+
amount2
|
|
939
|
+
);
|
|
940
|
+
const contract2 = new Contract(_M0AutomaticRoute.EXECUTOR_ENTRYPOINT, [
|
|
941
|
+
"function transferMLikeToken(uint256 amount, address sourceToken, uint16 destinationChainId, bytes32 destinationToken, bytes32 recipient, bytes32 refundAddress, (uint256 value, address refundAddress, bytes signedQuote, bytes instructions) executorArgs, bytes memory transceiverInstructions) external payable returns (bytes32 messageId)"
|
|
942
|
+
]);
|
|
943
|
+
const executorArgs = {
|
|
944
|
+
value: quote.estimatedCost,
|
|
945
|
+
refundAddress: senderAddress,
|
|
946
|
+
signedQuote: quote.signedQuote,
|
|
947
|
+
instructions: quote.relayInstructions
|
|
948
|
+
};
|
|
949
|
+
const txReq2 = await contract2.getFunction("transferMLikeToken").populateTransaction(
|
|
950
|
+
amount2,
|
|
951
|
+
sourceToken,
|
|
952
|
+
toChainId(destination.chain),
|
|
953
|
+
toUniversal(destination.chain, destinationToken).toString(),
|
|
954
|
+
receiver,
|
|
955
|
+
receiver,
|
|
956
|
+
executorArgs,
|
|
957
|
+
Uint8Array.from(Buffer.from("01000101", "hex")),
|
|
958
|
+
{ value: quote.estimatedCost }
|
|
959
|
+
);
|
|
960
|
+
yield ntt.createUnsignedTx(addFrom(txReq2, senderAddress), "Ntt.transfer");
|
|
961
|
+
return;
|
|
962
|
+
}
|
|
798
963
|
const contract = new Contract(ntt.managerAddress, [
|
|
799
964
|
"function transferMLikeToken(uint256 amount, address sourceToken, uint16 destinationChainId, bytes32 destinationToken, bytes32 recipient, bytes32 refundAddress) external payable returns (uint64 sequence)"
|
|
800
965
|
]);
|
|
@@ -805,7 +970,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
805
970
|
toUniversal(destination.chain, destinationToken).toString(),
|
|
806
971
|
receiver,
|
|
807
972
|
receiver,
|
|
808
|
-
{ value:
|
|
973
|
+
{ value: await ntt.quoteDeliveryPrice(destination.chain, options) }
|
|
809
974
|
);
|
|
810
975
|
yield ntt.createUnsignedTx(addFrom(txReq, senderAddress), "Ntt.transfer");
|
|
811
976
|
}
|
|
@@ -820,7 +985,7 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
820
985
|
}
|
|
821
986
|
async *transferSolanaExtension(ntt, sender, amount2, recipient, sourceToken, destinationToken, options, outboxItem) {
|
|
822
987
|
const router = new SolanaRoutes(ntt);
|
|
823
|
-
if (
|
|
988
|
+
if (router.getSolanaContracts().token === sourceToken) {
|
|
824
989
|
return ntt.transfer(sender, amount2, recipient, options);
|
|
825
990
|
}
|
|
826
991
|
const config = await ntt.getConfig();
|
|
@@ -855,18 +1020,34 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
855
1020
|
const tx = new Transaction();
|
|
856
1021
|
tx.feePayer = payerAddress;
|
|
857
1022
|
tx.add(...ixs);
|
|
858
|
-
if (
|
|
859
|
-
|
|
1023
|
+
if (this.requiresExecutor(recipient.chain)) {
|
|
1024
|
+
const quote = await this.getExecutorQuote(
|
|
1025
|
+
ntt.network,
|
|
1026
|
+
ntt.chain,
|
|
1027
|
+
recipient.chain,
|
|
1028
|
+
amount2
|
|
1029
|
+
);
|
|
1030
|
+
tx.add(
|
|
1031
|
+
router.getExecutorRelayIx(
|
|
1032
|
+
payerAddress,
|
|
1033
|
+
quote,
|
|
1034
|
+
recipient.chain,
|
|
1035
|
+
outboxItem.publicKey
|
|
1036
|
+
)
|
|
1037
|
+
);
|
|
1038
|
+
} else if (options.automatic) {
|
|
1039
|
+
if (!ntt.quoter) {
|
|
860
1040
|
throw new Error(
|
|
861
1041
|
"No quoter available, cannot initiate an automatic transfer."
|
|
862
1042
|
);
|
|
1043
|
+
}
|
|
863
1044
|
const fee = await ntt.quoteDeliveryPrice(recipient.chain, options);
|
|
864
1045
|
const relayIx = await ntt.quoter.createRequestRelayInstruction(
|
|
865
1046
|
payerAddress,
|
|
866
1047
|
outboxItem.publicKey,
|
|
867
1048
|
recipient.chain,
|
|
868
1049
|
Number(fee) / LAMPORTS_PER_SOL,
|
|
869
|
-
|
|
1050
|
+
0
|
|
870
1051
|
);
|
|
871
1052
|
tx.add(relayIx);
|
|
872
1053
|
}
|
|
@@ -946,11 +1127,44 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends routes.AutomaticRoute {
|
|
|
946
1127
|
}
|
|
947
1128
|
yield receipt;
|
|
948
1129
|
}
|
|
1130
|
+
async getExecutorQuote(network, sourceChain, destinationChain, amount2) {
|
|
1131
|
+
const wh = new Wormhole(network, [solana.Platform, evm.Platform]);
|
|
1132
|
+
const executorRoute = nttExecutorRoute(getExecutorConfig(network));
|
|
1133
|
+
const routeInstance = new executorRoute(wh);
|
|
1134
|
+
const resolveM = (chain) => {
|
|
1135
|
+
if (chainToPlatform(chain) === "Solana") {
|
|
1136
|
+
const c = chain;
|
|
1137
|
+
return SolanaRoutes.getSolanaContracts(network, c).token;
|
|
1138
|
+
}
|
|
1139
|
+
return _M0AutomaticRoute.EVM_CONTRACTS.token;
|
|
1140
|
+
};
|
|
1141
|
+
const transferRequest = await routes.RouteTransferRequest.create(wh, {
|
|
1142
|
+
source: Wormhole.tokenId(sourceChain, resolveM(sourceChain)),
|
|
1143
|
+
destination: Wormhole.tokenId(
|
|
1144
|
+
destinationChain,
|
|
1145
|
+
resolveM(destinationChain)
|
|
1146
|
+
)
|
|
1147
|
+
});
|
|
1148
|
+
const validated = await routeInstance.validate(transferRequest, {
|
|
1149
|
+
amount: amount2.toString()
|
|
1150
|
+
});
|
|
1151
|
+
if (!validated.valid) {
|
|
1152
|
+
throw new Error(`Validation failed: ${validated.error.message}`);
|
|
1153
|
+
}
|
|
1154
|
+
return await routeInstance.fetchExecutorQuote(
|
|
1155
|
+
transferRequest,
|
|
1156
|
+
validated.params
|
|
1157
|
+
);
|
|
1158
|
+
}
|
|
1159
|
+
requiresExecutor(destination) {
|
|
1160
|
+
return chainToPlatform(destination) === "Solana";
|
|
1161
|
+
}
|
|
949
1162
|
};
|
|
950
1163
|
// ntt does not support gas drop-off currently
|
|
951
1164
|
_M0AutomaticRoute.NATIVE_GAS_DROPOFF_SUPPORTED = false;
|
|
952
1165
|
// Wrapped M token address is the same on EVM chains
|
|
953
1166
|
_M0AutomaticRoute.EVM_WRAPPED_M_TOKEN = "0x437cc33344a0B27A429f795ff6B469C72698B291";
|
|
1167
|
+
_M0AutomaticRoute.EXECUTOR_ENTRYPOINT = "0x8518040a9cf9dfb55a4f099bb0eaabeefeb03643";
|
|
954
1168
|
// Contract addresses are the same on all EVM chains
|
|
955
1169
|
_M0AutomaticRoute.EVM_CONTRACTS = {
|
|
956
1170
|
// M token address is the same on EVM chains
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@m0-foundation/ntt-sdk-route",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": {
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -20,34 +20,35 @@
|
|
|
20
20
|
"files": [
|
|
21
21
|
"dist"
|
|
22
22
|
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"build": "$npm_execpath tsup --clean",
|
|
25
|
-
"clean": "rm -rf dist"
|
|
26
|
-
},
|
|
27
23
|
"devDependencies": {
|
|
28
24
|
"@changesets/cli": "^2.28.1",
|
|
29
25
|
"@types/bn.js": "^5.2.0",
|
|
30
26
|
"@types/node": "~20.17.17",
|
|
27
|
+
"ts-node": "^10.9.2",
|
|
31
28
|
"tsup": "~8.3.6",
|
|
32
29
|
"typescript": "~5.6.3"
|
|
33
30
|
},
|
|
34
31
|
"publishConfig": {
|
|
35
32
|
"access": "public"
|
|
36
33
|
},
|
|
37
|
-
"packageManager": "pnpm@10.2.0",
|
|
38
34
|
"dependencies": {
|
|
39
35
|
"@noble/hashes": "^1.8.0",
|
|
40
36
|
"@solana/spl-token": "^0.4.13",
|
|
41
37
|
"@solana/web3.js": "^1.98.2",
|
|
42
|
-
"@wormhole-foundation/sdk": "
|
|
43
|
-
"@wormhole-foundation/sdk-connect": "
|
|
44
|
-
"@wormhole-foundation/sdk-definitions-ntt": "
|
|
45
|
-
"@wormhole-foundation/sdk-evm": "
|
|
46
|
-
"@wormhole-foundation/sdk-evm-ntt": "
|
|
47
|
-
"@wormhole-foundation/sdk-route-ntt": "
|
|
48
|
-
"@wormhole-foundation/sdk-solana": "
|
|
49
|
-
"@wormhole-foundation/sdk-solana-ntt": "
|
|
38
|
+
"@wormhole-foundation/sdk": "3.4.7",
|
|
39
|
+
"@wormhole-foundation/sdk-connect": "3.4.7",
|
|
40
|
+
"@wormhole-foundation/sdk-definitions-ntt": "2.0.5",
|
|
41
|
+
"@wormhole-foundation/sdk-evm": "3.4.7",
|
|
42
|
+
"@wormhole-foundation/sdk-evm-ntt": "2.0.5",
|
|
43
|
+
"@wormhole-foundation/sdk-route-ntt": "2.0.5",
|
|
44
|
+
"@wormhole-foundation/sdk-solana": "3.4.7",
|
|
45
|
+
"@wormhole-foundation/sdk-solana-ntt": "2.0.5",
|
|
50
46
|
"bn.js": "^5.2.2",
|
|
51
47
|
"ethers": "^6.5.1"
|
|
48
|
+
},
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "$npm_execpath tsup --clean",
|
|
51
|
+
"clean": "rm -rf dist",
|
|
52
|
+
"test-bridge": "node --env-file=.env -r ts-node/register scripts/bridge.ts"
|
|
52
53
|
}
|
|
53
|
-
}
|
|
54
|
+
}
|