@m0-foundation/ntt-sdk-route 0.0.9 → 0.0.11
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 +33 -4
- package/dist/index.d.ts +33 -4
- package/dist/index.js +668 -20
- package/dist/index.mjs +665 -22
- package/package.json +13 -7
package/dist/index.js
CHANGED
|
@@ -2,24 +2,569 @@
|
|
|
2
2
|
|
|
3
3
|
var sdkConnect = require('@wormhole-foundation/sdk-connect');
|
|
4
4
|
var sdkDefinitionsNtt = require('@wormhole-foundation/sdk-definitions-ntt');
|
|
5
|
-
require('@wormhole-foundation/sdk-solana-ntt');
|
|
5
|
+
var sdkSolanaNtt = require('@wormhole-foundation/sdk-solana-ntt');
|
|
6
6
|
var sdkEvm = require('@wormhole-foundation/sdk-evm');
|
|
7
|
-
require('@wormhole-foundation/sdk-solana');
|
|
7
|
+
var sdkSolana = require('@wormhole-foundation/sdk-solana');
|
|
8
8
|
var sdkRouteNtt = require('@wormhole-foundation/sdk-route-ntt');
|
|
9
9
|
var ethers = require('ethers');
|
|
10
|
+
var web3_js = require('@solana/web3.js');
|
|
11
|
+
var splToken = require('@solana/spl-token');
|
|
12
|
+
var BN = require('bn.js');
|
|
13
|
+
var sha2 = require('@noble/hashes/sha2');
|
|
14
|
+
|
|
15
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
|
|
17
|
+
var BN__default = /*#__PURE__*/_interopDefault(BN);
|
|
10
18
|
|
|
11
19
|
// src/m0AutomaticRoute.ts
|
|
12
|
-
var
|
|
13
|
-
|
|
20
|
+
var SolanaRoutes = class _SolanaRoutes {
|
|
21
|
+
constructor(ntt) {
|
|
22
|
+
this.ntt = ntt;
|
|
23
|
+
this.network = ntt.network;
|
|
24
|
+
this.programs = _SolanaRoutes.getPrograms(this.network);
|
|
25
|
+
this.extPrograms = _SolanaRoutes.getExtPrograms(this.network);
|
|
26
|
+
}
|
|
27
|
+
static getPrograms(network) {
|
|
14
28
|
return {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
Mainnet: {
|
|
30
|
+
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
31
|
+
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
32
|
+
lut: pk("9JLRqBqkznKiSoNfotA4ywSRdnWb2fE76SiFrAfkaRCD"),
|
|
33
|
+
mMint: pk("mzerokyEX9TNDoK4o2YZQBDmMzjokAeN6M2g2S3pLJo"),
|
|
34
|
+
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
35
|
+
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
36
|
+
},
|
|
37
|
+
Testnet: {
|
|
38
|
+
swap: pk("MSwapi3WhNKMUGm9YrxGhypgUEt7wYQH3ZgG32XoWzH"),
|
|
39
|
+
earn: pk("mz2vDzjbQDUDXBH6FPF5s4odCJ4y8YLE5QWaZ8XdZ9Z"),
|
|
40
|
+
lut: pk("6GhuWPuAmiJeeSVsr58KjqHcAejJRndCx9BVtHkaYHUR"),
|
|
41
|
+
mMint: pk("mzeroZRGCah3j5xEWp2Nih3GDejSBbH1rbHoxDg8By6"),
|
|
42
|
+
portal: pk("mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY"),
|
|
43
|
+
quoter: pk("Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ")
|
|
44
|
+
}
|
|
45
|
+
}[network];
|
|
46
|
+
}
|
|
47
|
+
static getExtPrograms(network) {
|
|
48
|
+
return {
|
|
49
|
+
Mainnet: {
|
|
50
|
+
mzeroXDoBpRVhnEXBra27qzAMdxgpWVY3DzQW7xMVJp: {
|
|
51
|
+
program: pk("wMXX1K1nca5W4pZr1piETe78gcAVVrEFi9f4g46uXko"),
|
|
52
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
53
|
+
},
|
|
54
|
+
usdkbee86pkLyRmxfFCdkyySpxRb5ndCxVsK2BkRXwX: {
|
|
55
|
+
program: pk("extaykYu5AQcDm3qZAbiDN3yp6skqn6Nssj7veUUGZw"),
|
|
56
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
57
|
+
},
|
|
58
|
+
usdkyPPxgV7sfNyKb8eDz66ogPrkRXG3wS2FVb6LLUf: {
|
|
59
|
+
program: pk("extMahs9bUFMYcviKCvnSRaXgs5PcqmMzcnHRtTqE85"),
|
|
60
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
Testnet: {
|
|
64
|
+
mzeroXDoBpRVhnEXBra27qzAMdxgpWVY3DzQW7xMVJp: {
|
|
65
|
+
program: pk("wMXX1K1nca5W4pZr1piETe78gcAVVrEFi9f4g46uXko"),
|
|
66
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
67
|
+
},
|
|
68
|
+
usdkbee86pkLyRmxfFCdkyySpxRb5ndCxVsK2BkRXwX: {
|
|
69
|
+
program: pk("Fb2AsCKmPd4gKhabT6KsremSHMrJ8G2Mopnc6rDQZX9e"),
|
|
70
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
71
|
+
},
|
|
72
|
+
usdkyPPxgV7sfNyKb8eDz66ogPrkRXG3wS2FVb6LLUf: {
|
|
73
|
+
program: pk("3PskKTHgboCbUSQPMcCAZdZNFHbNvSoZ8zEFYANCdob7"),
|
|
74
|
+
tokenProgram: splToken.TOKEN_2022_PROGRAM_ID
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}[network];
|
|
78
|
+
}
|
|
79
|
+
static getSolanaContracts(chainContext) {
|
|
80
|
+
const programs = _SolanaRoutes.getPrograms(
|
|
81
|
+
chainContext.network
|
|
82
|
+
);
|
|
83
|
+
const extPrograms = _SolanaRoutes.getExtPrograms(
|
|
84
|
+
chainContext.network
|
|
85
|
+
);
|
|
86
|
+
return {
|
|
87
|
+
token: programs.mMint.toBase58(),
|
|
88
|
+
mLikeTokens: Object.keys(extPrograms),
|
|
89
|
+
manager: programs.portal.toBase58(),
|
|
90
|
+
transceiver: { wormhole: programs.portal.toBase58() },
|
|
91
|
+
quoter: programs.quoter.toBase58()
|
|
21
92
|
};
|
|
22
93
|
}
|
|
94
|
+
getTransferExtensionBurnIx(amount2, recipient, payer, outboxItem, extMint, destinationToken, shouldQueue = true) {
|
|
95
|
+
const recipientAddress = Buffer.alloc(32);
|
|
96
|
+
const dest = Buffer.from(recipient.address.toUint8Array());
|
|
97
|
+
dest.copy(recipientAddress);
|
|
98
|
+
if (destinationToken.length !== 32) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`destinationToken must be 32 bytes, got ${destinationToken.length} bytes`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
const extension = this.extPrograms[extMint.toBase58()];
|
|
104
|
+
if (!extension) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`No extension program found for mint ${extMint.toBase58()}`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const { program: extProgram, tokenProgram: extTokenProgram } = extension;
|
|
110
|
+
return new web3_js.TransactionInstruction({
|
|
111
|
+
programId: this.ntt.program.programId,
|
|
112
|
+
keys: [
|
|
113
|
+
{
|
|
114
|
+
pubkey: payer,
|
|
115
|
+
isSigner: true,
|
|
116
|
+
isWritable: true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
// config
|
|
120
|
+
pubkey: this.ntt.pdas.configAccount(),
|
|
121
|
+
isSigner: false,
|
|
122
|
+
isWritable: false
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
// m mint
|
|
126
|
+
pubkey: this.programs.mMint,
|
|
127
|
+
isSigner: false,
|
|
128
|
+
isWritable: true
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
// from (token auth m token account)
|
|
132
|
+
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
133
|
+
this.programs.mMint,
|
|
134
|
+
web3_js.PublicKey.findProgramAddressSync(
|
|
135
|
+
[Buffer.from("token_authority")],
|
|
136
|
+
this.ntt.program.programId
|
|
137
|
+
)[0],
|
|
138
|
+
true,
|
|
139
|
+
splToken.TOKEN_2022_PROGRAM_ID
|
|
140
|
+
),
|
|
141
|
+
isSigner: false,
|
|
142
|
+
isWritable: true
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
// m token program
|
|
146
|
+
pubkey: splToken.TOKEN_2022_PROGRAM_ID,
|
|
147
|
+
isSigner: false,
|
|
148
|
+
isWritable: false
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
// outbox item
|
|
152
|
+
pubkey: outboxItem,
|
|
153
|
+
isSigner: true,
|
|
154
|
+
isWritable: true
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
// outbox rate limit
|
|
158
|
+
pubkey: this.ntt.pdas.outboxRateLimitAccount(),
|
|
159
|
+
isSigner: false,
|
|
160
|
+
isWritable: true
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
// custody
|
|
164
|
+
pubkey: this.ntt.config.custody,
|
|
165
|
+
isSigner: false,
|
|
166
|
+
isWritable: true
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
// system program
|
|
170
|
+
pubkey: web3_js.SystemProgram.programId,
|
|
171
|
+
isSigner: false,
|
|
172
|
+
isWritable: false
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
// inbox rate limit
|
|
176
|
+
pubkey: this.ntt.pdas.inboxRateLimitAccount(recipient.chain),
|
|
177
|
+
isSigner: false,
|
|
178
|
+
isWritable: true
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
// peer
|
|
182
|
+
pubkey: this.ntt.pdas.peerAccount(recipient.chain),
|
|
183
|
+
isSigner: false,
|
|
184
|
+
isWritable: false
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
// session auth
|
|
188
|
+
pubkey: this.ntt.pdas.sessionAuthority(payer, {
|
|
189
|
+
amount: new BN__default.default(amount2),
|
|
190
|
+
recipientChain: {
|
|
191
|
+
id: 2
|
|
192
|
+
// Ethereum
|
|
193
|
+
},
|
|
194
|
+
recipientAddress: [...Array(32)],
|
|
195
|
+
shouldQueue: false
|
|
196
|
+
}),
|
|
197
|
+
isSigner: false,
|
|
198
|
+
isWritable: false
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
// token auth
|
|
202
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
203
|
+
[Buffer.from("token_authority")],
|
|
204
|
+
this.ntt.program.programId
|
|
205
|
+
)[0],
|
|
206
|
+
isSigner: false,
|
|
207
|
+
isWritable: false
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
// ext mint
|
|
211
|
+
pubkey: extMint,
|
|
212
|
+
isSigner: false,
|
|
213
|
+
isWritable: true
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
// swap global
|
|
217
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
218
|
+
[Buffer.from("global")],
|
|
219
|
+
this.programs.swap
|
|
220
|
+
)[0],
|
|
221
|
+
isSigner: false,
|
|
222
|
+
isWritable: false
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
// m global
|
|
226
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
227
|
+
[Buffer.from("global")],
|
|
228
|
+
this.programs.earn
|
|
229
|
+
)[0],
|
|
230
|
+
isSigner: false,
|
|
231
|
+
isWritable: false
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
// ext global
|
|
235
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
236
|
+
[Buffer.from("global")],
|
|
237
|
+
extProgram
|
|
238
|
+
)[0],
|
|
239
|
+
isSigner: false,
|
|
240
|
+
isWritable: true
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
// ext token account
|
|
244
|
+
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
245
|
+
extMint,
|
|
246
|
+
payer,
|
|
247
|
+
true,
|
|
248
|
+
extTokenProgram
|
|
249
|
+
),
|
|
250
|
+
isSigner: false,
|
|
251
|
+
isWritable: true
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
// ext m vault
|
|
255
|
+
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
256
|
+
this.programs.mMint,
|
|
257
|
+
web3_js.PublicKey.findProgramAddressSync(
|
|
258
|
+
[Buffer.from("m_vault")],
|
|
259
|
+
extProgram
|
|
260
|
+
)[0],
|
|
261
|
+
true,
|
|
262
|
+
splToken.TOKEN_2022_PROGRAM_ID
|
|
263
|
+
),
|
|
264
|
+
isSigner: false,
|
|
265
|
+
isWritable: true
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
// ext m vault auth
|
|
269
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
270
|
+
[Buffer.from("m_vault")],
|
|
271
|
+
extProgram
|
|
272
|
+
)[0],
|
|
273
|
+
isSigner: false,
|
|
274
|
+
isWritable: false
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
// ext mint auth
|
|
278
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
279
|
+
[Buffer.from("mint_authority")],
|
|
280
|
+
extProgram
|
|
281
|
+
)[0],
|
|
282
|
+
isSigner: false,
|
|
283
|
+
isWritable: false
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
// ext program
|
|
287
|
+
pubkey: extProgram,
|
|
288
|
+
isSigner: false,
|
|
289
|
+
isWritable: false
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
// swap program
|
|
293
|
+
pubkey: this.programs.swap,
|
|
294
|
+
isSigner: false,
|
|
295
|
+
isWritable: false
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
// ext token program
|
|
299
|
+
pubkey: extTokenProgram,
|
|
300
|
+
isSigner: false,
|
|
301
|
+
isWritable: false
|
|
302
|
+
}
|
|
303
|
+
],
|
|
304
|
+
data: Buffer.concat([
|
|
305
|
+
Buffer.from(sha2.sha256("global:transfer_extension_burn").subarray(0, 8)),
|
|
306
|
+
new BN__default.default(amount2).toArrayLike(Buffer, "le", 8),
|
|
307
|
+
// amount
|
|
308
|
+
new BN__default.default(sdkConnect.chainToChainId(recipient.chain)).toArrayLike(Buffer, "le", 2),
|
|
309
|
+
// chain_id
|
|
310
|
+
recipientAddress,
|
|
311
|
+
// recipient_address
|
|
312
|
+
destinationToken,
|
|
313
|
+
// destination_token
|
|
314
|
+
Buffer.from([Number(shouldQueue)])
|
|
315
|
+
// should_queue
|
|
316
|
+
])
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
getReleaseInboundMintExtensionIx(nttMessage, emitterChain, payer, extMint, extAta) {
|
|
320
|
+
const extension = this.extPrograms[extMint.toBase58()];
|
|
321
|
+
if (!extension) {
|
|
322
|
+
throw new Error(
|
|
323
|
+
`No extension program found for mint ${extMint.toBase58()}`
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
const { program: extProgram, tokenProgram: extTokenProgram } = extension;
|
|
327
|
+
return new web3_js.TransactionInstruction({
|
|
328
|
+
programId: this.ntt.program.programId,
|
|
329
|
+
keys: [
|
|
330
|
+
{
|
|
331
|
+
pubkey: payer,
|
|
332
|
+
isSigner: true,
|
|
333
|
+
isWritable: true
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
// config
|
|
337
|
+
pubkey: this.ntt.pdas.configAccount(),
|
|
338
|
+
isSigner: false,
|
|
339
|
+
isWritable: false
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
// inbox item
|
|
343
|
+
pubkey: this.ntt.pdas.inboxItemAccount(emitterChain, nttMessage),
|
|
344
|
+
isSigner: false,
|
|
345
|
+
isWritable: true
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
// recipient (mint to token auth which wraps to user)
|
|
349
|
+
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
350
|
+
this.ntt.config.mint,
|
|
351
|
+
web3_js.PublicKey.findProgramAddressSync(
|
|
352
|
+
[Buffer.from("token_authority")],
|
|
353
|
+
this.ntt.program.programId
|
|
354
|
+
)[0],
|
|
355
|
+
true,
|
|
356
|
+
splToken.TOKEN_2022_PROGRAM_ID
|
|
357
|
+
),
|
|
358
|
+
isSigner: false,
|
|
359
|
+
isWritable: true
|
|
360
|
+
},
|
|
361
|
+
{
|
|
362
|
+
// token auth
|
|
363
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
364
|
+
[Buffer.from("token_authority")],
|
|
365
|
+
this.ntt.program.programId
|
|
366
|
+
)[0],
|
|
367
|
+
isSigner: false,
|
|
368
|
+
isWritable: false
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
// m mint
|
|
372
|
+
pubkey: this.ntt.config.mint,
|
|
373
|
+
isSigner: false,
|
|
374
|
+
isWritable: true
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
// m token program
|
|
378
|
+
pubkey: splToken.TOKEN_2022_PROGRAM_ID,
|
|
379
|
+
isSigner: false,
|
|
380
|
+
isWritable: false
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
// custody
|
|
384
|
+
pubkey: this.ntt.config.custody,
|
|
385
|
+
isSigner: false,
|
|
386
|
+
isWritable: true
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
// earn program
|
|
390
|
+
pubkey: this.programs.earn,
|
|
391
|
+
isSigner: false,
|
|
392
|
+
isWritable: false
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
// m global
|
|
396
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
397
|
+
[Buffer.from("global")],
|
|
398
|
+
this.programs.earn
|
|
399
|
+
)[0],
|
|
400
|
+
isSigner: false,
|
|
401
|
+
isWritable: false
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
// ext mint
|
|
405
|
+
pubkey: extMint,
|
|
406
|
+
isSigner: false,
|
|
407
|
+
isWritable: true
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
// swap global
|
|
411
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
412
|
+
[Buffer.from("global")],
|
|
413
|
+
this.programs.swap
|
|
414
|
+
)[0],
|
|
415
|
+
isSigner: false,
|
|
416
|
+
isWritable: false
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
// ext global
|
|
420
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
421
|
+
[Buffer.from("global")],
|
|
422
|
+
extProgram
|
|
423
|
+
)[0],
|
|
424
|
+
isSigner: false,
|
|
425
|
+
isWritable: true
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
// ext m vault auth
|
|
429
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
430
|
+
[Buffer.from("m_vault")],
|
|
431
|
+
extProgram
|
|
432
|
+
)[0],
|
|
433
|
+
isSigner: false,
|
|
434
|
+
isWritable: false
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
// ext mint auth
|
|
438
|
+
pubkey: web3_js.PublicKey.findProgramAddressSync(
|
|
439
|
+
[Buffer.from("mint_authority")],
|
|
440
|
+
extProgram
|
|
441
|
+
)[0],
|
|
442
|
+
isSigner: false,
|
|
443
|
+
isWritable: false
|
|
444
|
+
},
|
|
445
|
+
{
|
|
446
|
+
// ext m vault
|
|
447
|
+
pubkey: splToken.getAssociatedTokenAddressSync(
|
|
448
|
+
this.ntt.config.mint,
|
|
449
|
+
web3_js.PublicKey.findProgramAddressSync(
|
|
450
|
+
[Buffer.from("m_vault")],
|
|
451
|
+
extProgram
|
|
452
|
+
)[0],
|
|
453
|
+
true,
|
|
454
|
+
splToken.TOKEN_2022_PROGRAM_ID
|
|
455
|
+
),
|
|
456
|
+
isSigner: false,
|
|
457
|
+
isWritable: true
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
// ext token account
|
|
461
|
+
pubkey: extAta,
|
|
462
|
+
isSigner: false,
|
|
463
|
+
isWritable: true
|
|
464
|
+
},
|
|
465
|
+
{
|
|
466
|
+
// ext token account
|
|
467
|
+
pubkey: this.programs.swap,
|
|
468
|
+
isSigner: false,
|
|
469
|
+
isWritable: false
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
// ext program
|
|
473
|
+
pubkey: extProgram,
|
|
474
|
+
isSigner: false,
|
|
475
|
+
isWritable: false
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
// ext token program
|
|
479
|
+
pubkey: extTokenProgram,
|
|
480
|
+
isSigner: false,
|
|
481
|
+
isWritable: false
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
// system program
|
|
485
|
+
pubkey: web3_js.SystemProgram.programId,
|
|
486
|
+
isSigner: false,
|
|
487
|
+
isWritable: false
|
|
488
|
+
}
|
|
489
|
+
],
|
|
490
|
+
data: Buffer.concat([
|
|
491
|
+
Buffer.from(
|
|
492
|
+
sha2.sha256("global:release_inbound_mint_extension").subarray(0, 8)
|
|
493
|
+
)
|
|
494
|
+
])
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
async getAddressLookupTableAccounts(connection) {
|
|
498
|
+
const info = await connection.getAccountInfo(this.programs.lut);
|
|
499
|
+
return new web3_js.AddressLookupTableAccount({
|
|
500
|
+
key: this.programs.lut,
|
|
501
|
+
state: web3_js.AddressLookupTableAccount.deserialize(info.data)
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
static async createReleaseInboundMintInstruction(ntt, args) {
|
|
505
|
+
const router = new _SolanaRoutes(ntt);
|
|
506
|
+
const { additionalPayload } = args.nttMessage.payload;
|
|
507
|
+
if (additionalPayload.length < 40) {
|
|
508
|
+
throw new Error(
|
|
509
|
+
`Invalid additionalPayload length: ${additionalPayload.length}, expected at least 40 bytes`
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
const destinationMint = new web3_js.PublicKey(
|
|
513
|
+
// first 8 bytes is the index, next 32 bytes is the mint address
|
|
514
|
+
additionalPayload.slice(8, 40)
|
|
515
|
+
);
|
|
516
|
+
if (destinationMint.equals(ntt.config.mint)) {
|
|
517
|
+
return [
|
|
518
|
+
await sdkSolanaNtt.NTT.createReleaseInboundMintInstruction(
|
|
519
|
+
ntt.program,
|
|
520
|
+
ntt.config,
|
|
521
|
+
args
|
|
522
|
+
)
|
|
523
|
+
];
|
|
524
|
+
}
|
|
525
|
+
const extPrograms = router.extPrograms[destinationMint.toBase58()];
|
|
526
|
+
if (!extPrograms) {
|
|
527
|
+
throw new Error(
|
|
528
|
+
`No extension program found for mint ${destinationMint.toBase58()}`
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
const extAta = splToken.getAssociatedTokenAddressSync(
|
|
532
|
+
destinationMint,
|
|
533
|
+
args.recipient,
|
|
534
|
+
true,
|
|
535
|
+
extPrograms.tokenProgram
|
|
536
|
+
);
|
|
537
|
+
const ixs = [];
|
|
538
|
+
const acctInfo = await ntt.connection.getAccountInfo(extAta);
|
|
539
|
+
if (acctInfo === null) {
|
|
540
|
+
ixs.push(
|
|
541
|
+
splToken.createAssociatedTokenAccountInstruction(
|
|
542
|
+
args.payer,
|
|
543
|
+
extAta,
|
|
544
|
+
args.recipient,
|
|
545
|
+
destinationMint,
|
|
546
|
+
extPrograms.tokenProgram
|
|
547
|
+
)
|
|
548
|
+
);
|
|
549
|
+
}
|
|
550
|
+
ixs.push(
|
|
551
|
+
router.getReleaseInboundMintExtensionIx(
|
|
552
|
+
args.nttMessage,
|
|
553
|
+
args.chain,
|
|
554
|
+
args.payer,
|
|
555
|
+
destinationMint,
|
|
556
|
+
extAta
|
|
557
|
+
)
|
|
558
|
+
);
|
|
559
|
+
return ixs;
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
function pk(address) {
|
|
563
|
+
return new web3_js.PublicKey(address);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/m0AutomaticRoute.ts
|
|
567
|
+
var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.AutomaticRoute {
|
|
23
568
|
static supportedNetworks() {
|
|
24
569
|
return ["Mainnet", "Testnet"];
|
|
25
570
|
}
|
|
@@ -29,9 +574,15 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
29
574
|
static supportedChains(network) {
|
|
30
575
|
switch (network) {
|
|
31
576
|
case "Mainnet":
|
|
32
|
-
return ["Ethereum", "Arbitrum", "Optimism", "Solana"];
|
|
577
|
+
return ["Ethereum", "Arbitrum", "Optimism", "Solana", "Fogo"];
|
|
33
578
|
case "Testnet":
|
|
34
|
-
return [
|
|
579
|
+
return [
|
|
580
|
+
"Sepolia",
|
|
581
|
+
"ArbitrumSepolia",
|
|
582
|
+
"OptimismSepolia",
|
|
583
|
+
"Solana",
|
|
584
|
+
"Fogo"
|
|
585
|
+
];
|
|
35
586
|
default:
|
|
36
587
|
throw new Error(`Unsupported network: ${network}`);
|
|
37
588
|
}
|
|
@@ -51,7 +602,9 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
51
602
|
case "ArbitrumSepolia":
|
|
52
603
|
return this.EVM_CONTRACTS;
|
|
53
604
|
case "Solana":
|
|
54
|
-
return
|
|
605
|
+
return SolanaRoutes.getSolanaContracts(chainContext);
|
|
606
|
+
case "Fogo":
|
|
607
|
+
return SolanaRoutes.getSolanaContracts(chainContext);
|
|
55
608
|
default:
|
|
56
609
|
throw new Error(`Unsupported chain: ${chainContext.chain}`);
|
|
57
610
|
}
|
|
@@ -69,8 +622,9 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
69
622
|
return [];
|
|
70
623
|
}
|
|
71
624
|
const { token: mToken, mLikeTokens } = this.getContracts(toChain);
|
|
72
|
-
|
|
73
|
-
|
|
625
|
+
return [mToken, ...mLikeTokens].map(
|
|
626
|
+
(x) => sdkConnect.Wormhole.tokenId(toChain.chain, x)
|
|
627
|
+
);
|
|
74
628
|
}
|
|
75
629
|
static isProtocolSupported(chain) {
|
|
76
630
|
return chain.supportsProtocol("Ntt");
|
|
@@ -165,14 +719,38 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
165
719
|
const platform = sdkConnect.chainToPlatform(fromChain.chain);
|
|
166
720
|
const transferAmount = sdkConnect.amount.units(params.normalizedParams.amount);
|
|
167
721
|
const options = params.normalizedParams.options;
|
|
168
|
-
if (platform
|
|
722
|
+
if (!_M0AutomaticRoute.isPlatformSupported(platform))
|
|
169
723
|
throw new Error(`Unsupported platform ${platform}`);
|
|
170
724
|
const ntt = await fromChain.getProtocol("Ntt", {
|
|
171
725
|
ntt: _M0AutomaticRoute.getContracts(fromChain)
|
|
172
726
|
});
|
|
173
727
|
const sourceToken = sdkConnect.canonicalAddress(request.source.id);
|
|
174
728
|
const destinationToken = sdkConnect.canonicalAddress(request.destination.id);
|
|
175
|
-
const initXfer = platform === "Evm" ?
|
|
729
|
+
const initXfer = platform === "Evm" ? (
|
|
730
|
+
// for EVM call transferMLike function
|
|
731
|
+
this.transferMLike(
|
|
732
|
+
ntt,
|
|
733
|
+
// @ts-ignore
|
|
734
|
+
sender,
|
|
735
|
+
transferAmount,
|
|
736
|
+
to,
|
|
737
|
+
sourceToken,
|
|
738
|
+
destinationToken,
|
|
739
|
+
options
|
|
740
|
+
)
|
|
741
|
+
) : (
|
|
742
|
+
// for Solana use custom transfer instruction
|
|
743
|
+
this.transferSolanaExtension(
|
|
744
|
+
ntt,
|
|
745
|
+
// @ts-ignore
|
|
746
|
+
sender,
|
|
747
|
+
transferAmount,
|
|
748
|
+
to,
|
|
749
|
+
sourceToken,
|
|
750
|
+
destinationToken,
|
|
751
|
+
options
|
|
752
|
+
)
|
|
753
|
+
);
|
|
176
754
|
const txids = await sdkConnect.signSendWait(fromChain, initXfer, signer);
|
|
177
755
|
return {
|
|
178
756
|
from: fromChain.chain,
|
|
@@ -232,6 +810,75 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
232
810
|
parallelizable
|
|
233
811
|
);
|
|
234
812
|
}
|
|
813
|
+
async *transferSolanaExtension(ntt, sender, amount2, recipient, sourceToken, destinationToken, options) {
|
|
814
|
+
const router = new SolanaRoutes(ntt);
|
|
815
|
+
if ((await ntt.getConfig()).mint.toBase58() === sourceToken) {
|
|
816
|
+
return ntt.transfer(sender, amount2, recipient, options);
|
|
817
|
+
}
|
|
818
|
+
const config = await ntt.getConfig();
|
|
819
|
+
if (config.paused) throw new Error("Contract is paused");
|
|
820
|
+
const outboxItem = web3_js.Keypair.generate();
|
|
821
|
+
const payerAddress = new sdkSolana.SolanaAddress(sender).unwrap();
|
|
822
|
+
const ixs = [
|
|
823
|
+
router.getTransferExtensionBurnIx(
|
|
824
|
+
amount2,
|
|
825
|
+
recipient,
|
|
826
|
+
new web3_js.PublicKey(sender.toUint8Array()),
|
|
827
|
+
outboxItem.publicKey,
|
|
828
|
+
new web3_js.PublicKey(sourceToken),
|
|
829
|
+
sdkConnect.toUniversal(recipient.chain, destinationToken).toUint8Array(),
|
|
830
|
+
options.queue
|
|
831
|
+
)
|
|
832
|
+
];
|
|
833
|
+
for (let ix = 0; ix < ntt.transceivers.length; ++ix) {
|
|
834
|
+
if (ix === 0) {
|
|
835
|
+
const whTransceiver = await ntt.getWormholeTransceiver();
|
|
836
|
+
if (!whTransceiver) {
|
|
837
|
+
throw new Error("wormhole transceiver not found");
|
|
838
|
+
}
|
|
839
|
+
const releaseIx = await whTransceiver.createReleaseWormholeOutboundIx(
|
|
840
|
+
payerAddress,
|
|
841
|
+
outboxItem.publicKey,
|
|
842
|
+
!options.queue
|
|
843
|
+
);
|
|
844
|
+
ixs.push(releaseIx);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
const tx = new web3_js.Transaction();
|
|
848
|
+
tx.feePayer = payerAddress;
|
|
849
|
+
tx.add(...ixs);
|
|
850
|
+
if (options.automatic) {
|
|
851
|
+
if (!ntt.quoter)
|
|
852
|
+
throw new Error(
|
|
853
|
+
"No quoter available, cannot initiate an automatic transfer."
|
|
854
|
+
);
|
|
855
|
+
const fee = await ntt.quoteDeliveryPrice(recipient.chain, options);
|
|
856
|
+
const relayIx = await ntt.quoter.createRequestRelayInstruction(
|
|
857
|
+
payerAddress,
|
|
858
|
+
outboxItem.publicKey,
|
|
859
|
+
recipient.chain,
|
|
860
|
+
Number(fee) / web3_js.LAMPORTS_PER_SOL,
|
|
861
|
+
Number(options.gasDropoff ?? 0n) / sdkSolanaNtt.WEI_PER_GWEI
|
|
862
|
+
);
|
|
863
|
+
tx.add(relayIx);
|
|
864
|
+
}
|
|
865
|
+
const luts = [];
|
|
866
|
+
try {
|
|
867
|
+
luts.push(await ntt.getAddressLookupTable());
|
|
868
|
+
luts.push(await router.getAddressLookupTableAccounts(ntt.connection));
|
|
869
|
+
} catch {
|
|
870
|
+
}
|
|
871
|
+
const messageV0 = new web3_js.TransactionMessage({
|
|
872
|
+
payerKey: payerAddress,
|
|
873
|
+
instructions: tx.instructions,
|
|
874
|
+
recentBlockhash: (await ntt.connection.getLatestBlockhash()).blockhash
|
|
875
|
+
}).compileToV0Message(luts);
|
|
876
|
+
const vtx = new web3_js.VersionedTransaction(messageV0);
|
|
877
|
+
yield ntt.createUnsignedTx(
|
|
878
|
+
{ transaction: vtx, signers: [outboxItem] },
|
|
879
|
+
"Ntt.Transfer"
|
|
880
|
+
);
|
|
881
|
+
}
|
|
235
882
|
async *track(receipt, timeout) {
|
|
236
883
|
const isEvmPlatform = (chain) => sdkConnect.chainToPlatform(chain) === "Evm";
|
|
237
884
|
if (sdkConnect.isSourceInitiated(receipt) || sdkConnect.isSourceFinalized(receipt)) {
|
|
@@ -274,7 +921,9 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
274
921
|
}
|
|
275
922
|
}
|
|
276
923
|
if (sdkConnect.isRedeemed(receipt)) {
|
|
277
|
-
const {
|
|
924
|
+
const {
|
|
925
|
+
attestation: { attestation: vaa }
|
|
926
|
+
} = receipt;
|
|
278
927
|
const payload = vaa.payloadName === "WormholeTransfer" ? vaa.payload : vaa.payload["payload"];
|
|
279
928
|
const isExecuted = isEvmPlatform(receipt.to) ? await ntt.manager.isMessageExecuted(
|
|
280
929
|
sdkDefinitionsNtt.Ntt.messageDigest(vaa.emitterChain, payload["nttManagerPayload"])
|
|
@@ -294,8 +943,6 @@ var _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.Automa
|
|
|
294
943
|
_M0AutomaticRoute.NATIVE_GAS_DROPOFF_SUPPORTED = false;
|
|
295
944
|
// Wrapped M token address is the same on EVM chains
|
|
296
945
|
_M0AutomaticRoute.EVM_WRAPPED_M_TOKEN = "0x437cc33344a0B27A429f795ff6B469C72698B291";
|
|
297
|
-
_M0AutomaticRoute.SOLANA_MAINNET_M_TOKEN = "mzerokyEX9TNDoK4o2YZQBDmMzjokAeN6M2g2S3pLJo";
|
|
298
|
-
_M0AutomaticRoute.SOLANA_TESTNET_M_TOKEN = "mzeroZRGCah3j5xEWp2Nih3GDejSBbH1rbHoxDg8By6";
|
|
299
946
|
// Contract addresses are the same on all EVM chains
|
|
300
947
|
_M0AutomaticRoute.EVM_CONTRACTS = {
|
|
301
948
|
// M token address is the same on EVM chains
|
|
@@ -311,3 +958,4 @@ _M0AutomaticRoute.meta = { name: "M0AutomaticRoute", provider: "M0" };
|
|
|
311
958
|
var M0AutomaticRoute = _M0AutomaticRoute;
|
|
312
959
|
|
|
313
960
|
exports.M0AutomaticRoute = M0AutomaticRoute;
|
|
961
|
+
exports.SolanaRoutes = SolanaRoutes;
|