@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.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 _M0AutomaticRoute = class _M0AutomaticRoute extends sdkConnect.routes.AutomaticRoute {
13
- static solanaContracts(network) {
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
- token: network == "Mainnet" ? this.SOLANA_MAINNET_M_TOKEN : this.SOLANA_TESTNET_M_TOKEN,
16
- // Only M token can be bridged from Solana
17
- mLikeTokens: [],
18
- manager: "mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY",
19
- transceiver: { wormhole: "mzp1q2j5Hr1QuLC3KFBCAUz5aUckT6qyuZKZ3WJnMmY" },
20
- quoter: "Nqd6XqA8LbsCuG8MLWWuP865NV6jR1MbXeKxD4HLKDJ"
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 ["Sepolia", "ArbitrumSepolia", "OptimismSepolia", "Solana"];
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 this.solanaContracts(chainContext.network);
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
- const toMToken = sdkConnect.Wormhole.tokenId(toChain.chain, mToken);
73
- return sdkConnect.chainToPlatform(fromChain.chain) === "Solana" ? [toMToken] : [toMToken, ...mLikeTokens.map((x) => sdkConnect.Wormhole.tokenId(toChain.chain, x))];
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 !== "Evm" && platform !== "Solana")
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" ? this.transferMLike(ntt, sender, transferAmount, to, sourceToken, destinationToken, options) : ntt.transfer(sender, transferAmount, to, options);
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 { attestation: { attestation: vaa } } = receipt;
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;