@xswap-link/sdk 0.10.8 → 0.10.9

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.
Files changed (69) hide show
  1. package/.eslintrc.json +10 -1
  2. package/CHANGELOG.md +6 -0
  3. package/dist/index.global.js +331 -331
  4. package/dist/index.js +9 -9
  5. package/dist/index.mjs +9 -9
  6. package/package.json +6 -3
  7. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +106 -9
  8. package/src/components/Swap/SwapView/SwapButton/index.tsx +11 -11
  9. package/src/constants/index.ts +19 -2
  10. package/src/context/SwapProvider.tsx +7 -3
  11. package/src/services/api.ts +1 -0
  12. package/src/services/svm/README.md +483 -0
  13. package/src/services/svm/bindings/accounts/AllowedOfframp.ts +73 -0
  14. package/src/services/svm/bindings/accounts/Config.ts +153 -0
  15. package/src/services/svm/bindings/accounts/DestChain.ts +113 -0
  16. package/src/services/svm/bindings/accounts/Nonce.ts +97 -0
  17. package/src/services/svm/bindings/accounts/index.ts +15 -0
  18. package/src/services/svm/bindings/accounts/tokenAdminRegistry.ts +128 -0
  19. package/src/services/svm/bindings/errors/anchor.ts +773 -0
  20. package/src/services/svm/bindings/errors/custom.ts +375 -0
  21. package/src/services/svm/bindings/errors/index.ts +62 -0
  22. package/src/services/svm/bindings/instructions/ccipSend.ts +112 -0
  23. package/src/services/svm/bindings/instructions/getFee.ts +73 -0
  24. package/src/services/svm/bindings/instructions/index.ts +4 -0
  25. package/src/services/svm/bindings/programId.ts +6 -0
  26. package/src/services/svm/bindings/types/BaseChain.ts +92 -0
  27. package/src/services/svm/bindings/types/BaseConfig.ts +184 -0
  28. package/src/services/svm/bindings/types/CodeVersion.ts +88 -0
  29. package/src/services/svm/bindings/types/CrossChainAmount.ts +53 -0
  30. package/src/services/svm/bindings/types/DestChainConfig.ts +76 -0
  31. package/src/services/svm/bindings/types/DestChainState.ts +76 -0
  32. package/src/services/svm/bindings/types/GetFeeResult.ts +72 -0
  33. package/src/services/svm/bindings/types/LockOrBurnInV1.ts +102 -0
  34. package/src/services/svm/bindings/types/LockOrBurnOutV1.ts +79 -0
  35. package/src/services/svm/bindings/types/RampMessageHeader.ts +94 -0
  36. package/src/services/svm/bindings/types/RateLimitConfig.ts +72 -0
  37. package/src/services/svm/bindings/types/RateLimitTokenBucket.ts +76 -0
  38. package/src/services/svm/bindings/types/ReleaseOrMintInV1.ts +156 -0
  39. package/src/services/svm/bindings/types/ReleaseOrMintOutV1.ts +53 -0
  40. package/src/services/svm/bindings/types/RemoteAddress.ts +61 -0
  41. package/src/services/svm/bindings/types/RemoteConfig.ts +86 -0
  42. package/src/services/svm/bindings/types/RestoreOnAction.ts +120 -0
  43. package/src/services/svm/bindings/types/SVM2AnyMessage.ts +128 -0
  44. package/src/services/svm/bindings/types/SVM2AnyRampMessage.ts +166 -0
  45. package/src/services/svm/bindings/types/SVM2AnyTokenTransfer.ts +118 -0
  46. package/src/services/svm/bindings/types/SVMTokenAmount.ts +64 -0
  47. package/src/services/svm/bindings/types/index.ts +78 -0
  48. package/src/services/svm/core/client/accounts.ts +97 -0
  49. package/src/services/svm/core/client/events.ts +95 -0
  50. package/src/services/svm/core/client/fee.ts +279 -0
  51. package/src/services/svm/core/client/index.ts +150 -0
  52. package/src/services/svm/core/client/send.ts +607 -0
  53. package/src/services/svm/core/client/utils.ts +131 -0
  54. package/src/services/svm/core/models.ts +236 -0
  55. package/src/services/svm/index.ts +32 -0
  56. package/src/services/svm/utils/conversion.ts +62 -0
  57. package/src/services/svm/utils/errors.ts +51 -0
  58. package/src/services/svm/utils/keypair.ts +19 -0
  59. package/src/services/svm/utils/logger.ts +171 -0
  60. package/src/services/svm/utils/pdas/common.ts +15 -0
  61. package/src/services/svm/utils/pdas/feeQuoter.ts +68 -0
  62. package/src/services/svm/utils/pdas/index.ts +12 -0
  63. package/src/services/svm/utils/pdas/receiver.ts +58 -0
  64. package/src/services/svm/utils/pdas/rmnRemote.ts +23 -0
  65. package/src/services/svm/utils/pdas/router.ts +328 -0
  66. package/src/services/svm/utils/pdas/tokenpool.ts +161 -0
  67. package/src/services/svm/utils/transaction.ts +132 -0
  68. package/src/utils/validation.ts +7 -3
  69. package/tsconfig.json +2 -1
@@ -0,0 +1,375 @@
1
+ export type CustomError =
2
+ | Unauthorized
3
+ | InvalidRMNRemoteAddress
4
+ | InvalidInputsMint
5
+ | InvalidVersion
6
+ | FeeTokenMismatch
7
+ | RedundantOwnerProposal
8
+ | ReachedMaxSequenceNumber
9
+ | InvalidInputsTokenIndices
10
+ | InvalidInputsPoolAccounts
11
+ | InvalidInputsTokenAccounts
12
+ | InvalidInputsTokenAdminRegistryAccounts
13
+ | InvalidInputsLookupTableAccounts
14
+ | InvalidInputsLookupTableAccountWritable
15
+ | InvalidInputsTokenAmount
16
+ | InvalidInputsTransferAllAmount
17
+ | InvalidInputsAtaAddress
18
+ | InvalidInputsAtaWritable
19
+ | InvalidInputsChainSelector
20
+ | InsufficientLamports
21
+ | InsufficientFunds
22
+ | SourceTokenDataTooLarge
23
+ | InvalidTokenAdminRegistryInputsZeroAddress
24
+ | InvalidTokenAdminRegistryProposedAdmin
25
+ | SenderNotAllowed
26
+ | InvalidCodeVersion
27
+ | InvalidCcipVersionRollback
28
+
29
+ export class Unauthorized extends Error {
30
+ static readonly code = 7000
31
+ readonly code = 7000
32
+ readonly name = "Unauthorized"
33
+ readonly msg = "The signer is unauthorized"
34
+
35
+ constructor(readonly logs?: string[]) {
36
+ super("7000: The signer is unauthorized")
37
+ }
38
+ }
39
+
40
+ export class InvalidRMNRemoteAddress extends Error {
41
+ static readonly code = 7001
42
+ readonly code = 7001
43
+ readonly name = "InvalidRMNRemoteAddress"
44
+ readonly msg = "Invalid RMN Remote Address"
45
+
46
+ constructor(readonly logs?: string[]) {
47
+ super("7001: Invalid RMN Remote Address")
48
+ }
49
+ }
50
+
51
+ export class InvalidInputsMint extends Error {
52
+ static readonly code = 7002
53
+ readonly code = 7002
54
+ readonly name = "InvalidInputsMint"
55
+ readonly msg = "Mint account input is invalid"
56
+
57
+ constructor(readonly logs?: string[]) {
58
+ super("7002: Mint account input is invalid")
59
+ }
60
+ }
61
+
62
+ export class InvalidVersion extends Error {
63
+ static readonly code = 7003
64
+ readonly code = 7003
65
+ readonly name = "InvalidVersion"
66
+ readonly msg = "Invalid version of the onchain state"
67
+
68
+ constructor(readonly logs?: string[]) {
69
+ super("7003: Invalid version of the onchain state")
70
+ }
71
+ }
72
+
73
+ export class FeeTokenMismatch extends Error {
74
+ static readonly code = 7004
75
+ readonly code = 7004
76
+ readonly name = "FeeTokenMismatch"
77
+ readonly msg = "Fee token doesn't match transfer token"
78
+
79
+ constructor(readonly logs?: string[]) {
80
+ super("7004: Fee token doesn't match transfer token")
81
+ }
82
+ }
83
+
84
+ export class RedundantOwnerProposal extends Error {
85
+ static readonly code = 7005
86
+ readonly code = 7005
87
+ readonly name = "RedundantOwnerProposal"
88
+ readonly msg = "Proposed owner is the current owner"
89
+
90
+ constructor(readonly logs?: string[]) {
91
+ super("7005: Proposed owner is the current owner")
92
+ }
93
+ }
94
+
95
+ export class ReachedMaxSequenceNumber extends Error {
96
+ static readonly code = 7006
97
+ readonly code = 7006
98
+ readonly name = "ReachedMaxSequenceNumber"
99
+ readonly msg = "Reached max sequence number"
100
+
101
+ constructor(readonly logs?: string[]) {
102
+ super("7006: Reached max sequence number")
103
+ }
104
+ }
105
+
106
+ export class InvalidInputsTokenIndices extends Error {
107
+ static readonly code = 7007
108
+ readonly code = 7007
109
+ readonly name = "InvalidInputsTokenIndices"
110
+ readonly msg = "Invalid pool account account indices"
111
+
112
+ constructor(readonly logs?: string[]) {
113
+ super("7007: Invalid pool account account indices")
114
+ }
115
+ }
116
+
117
+ export class InvalidInputsPoolAccounts extends Error {
118
+ static readonly code = 7008
119
+ readonly code = 7008
120
+ readonly name = "InvalidInputsPoolAccounts"
121
+ readonly msg = "Invalid pool accounts"
122
+
123
+ constructor(readonly logs?: string[]) {
124
+ super("7008: Invalid pool accounts")
125
+ }
126
+ }
127
+
128
+ export class InvalidInputsTokenAccounts extends Error {
129
+ static readonly code = 7009
130
+ readonly code = 7009
131
+ readonly name = "InvalidInputsTokenAccounts"
132
+ readonly msg = "Invalid token accounts"
133
+
134
+ constructor(readonly logs?: string[]) {
135
+ super("7009: Invalid token accounts")
136
+ }
137
+ }
138
+
139
+ export class InvalidInputsTokenAdminRegistryAccounts extends Error {
140
+ static readonly code = 7010
141
+ readonly code = 7010
142
+ readonly name = "InvalidInputsTokenAdminRegistryAccounts"
143
+ readonly msg = "Invalid Token Admin Registry account"
144
+
145
+ constructor(readonly logs?: string[]) {
146
+ super("7010: Invalid Token Admin Registry account")
147
+ }
148
+ }
149
+
150
+ export class InvalidInputsLookupTableAccounts extends Error {
151
+ static readonly code = 7011
152
+ readonly code = 7011
153
+ readonly name = "InvalidInputsLookupTableAccounts"
154
+ readonly msg = "Invalid LookupTable account"
155
+
156
+ constructor(readonly logs?: string[]) {
157
+ super("7011: Invalid LookupTable account")
158
+ }
159
+ }
160
+
161
+ export class InvalidInputsLookupTableAccountWritable extends Error {
162
+ static readonly code = 7012
163
+ readonly code = 7012
164
+ readonly name = "InvalidInputsLookupTableAccountWritable"
165
+ readonly msg = "Invalid LookupTable account writable access"
166
+
167
+ constructor(readonly logs?: string[]) {
168
+ super("7012: Invalid LookupTable account writable access")
169
+ }
170
+ }
171
+
172
+ export class InvalidInputsTokenAmount extends Error {
173
+ static readonly code = 7013
174
+ readonly code = 7013
175
+ readonly name = "InvalidInputsTokenAmount"
176
+ readonly msg = "Cannot send zero tokens"
177
+
178
+ constructor(readonly logs?: string[]) {
179
+ super("7013: Cannot send zero tokens")
180
+ }
181
+ }
182
+
183
+ export class InvalidInputsTransferAllAmount extends Error {
184
+ static readonly code = 7014
185
+ readonly code = 7014
186
+ readonly name = "InvalidInputsTransferAllAmount"
187
+ readonly msg = "Must specify zero amount to send alongside transfer_all"
188
+
189
+ constructor(readonly logs?: string[]) {
190
+ super("7014: Must specify zero amount to send alongside transfer_all")
191
+ }
192
+ }
193
+
194
+ export class InvalidInputsAtaAddress extends Error {
195
+ static readonly code = 7015
196
+ readonly code = 7015
197
+ readonly name = "InvalidInputsAtaAddress"
198
+ readonly msg = "Invalid Associated Token Account address"
199
+
200
+ constructor(readonly logs?: string[]) {
201
+ super("7015: Invalid Associated Token Account address")
202
+ }
203
+ }
204
+
205
+ export class InvalidInputsAtaWritable extends Error {
206
+ static readonly code = 7016
207
+ readonly code = 7016
208
+ readonly name = "InvalidInputsAtaWritable"
209
+ readonly msg = "Invalid Associated Token Account writable flag"
210
+
211
+ constructor(readonly logs?: string[]) {
212
+ super("7016: Invalid Associated Token Account writable flag")
213
+ }
214
+ }
215
+
216
+ export class InvalidInputsChainSelector extends Error {
217
+ static readonly code = 7017
218
+ readonly code = 7017
219
+ readonly name = "InvalidInputsChainSelector"
220
+ readonly msg = "Chain selector is invalid"
221
+
222
+ constructor(readonly logs?: string[]) {
223
+ super("7017: Chain selector is invalid")
224
+ }
225
+ }
226
+
227
+ export class InsufficientLamports extends Error {
228
+ static readonly code = 7018
229
+ readonly code = 7018
230
+ readonly name = "InsufficientLamports"
231
+ readonly msg = "Insufficient lamports"
232
+
233
+ constructor(readonly logs?: string[]) {
234
+ super("7018: Insufficient lamports")
235
+ }
236
+ }
237
+
238
+ export class InsufficientFunds extends Error {
239
+ static readonly code = 7019
240
+ readonly code = 7019
241
+ readonly name = "InsufficientFunds"
242
+ readonly msg = "Insufficient funds"
243
+
244
+ constructor(readonly logs?: string[]) {
245
+ super("7019: Insufficient funds")
246
+ }
247
+ }
248
+
249
+ export class SourceTokenDataTooLarge extends Error {
250
+ static readonly code = 7020
251
+ readonly code = 7020
252
+ readonly name = "SourceTokenDataTooLarge"
253
+ readonly msg = "Source token data is too large"
254
+
255
+ constructor(readonly logs?: string[]) {
256
+ super("7020: Source token data is too large")
257
+ }
258
+ }
259
+
260
+ export class InvalidTokenAdminRegistryInputsZeroAddress extends Error {
261
+ static readonly code = 7021
262
+ readonly code = 7021
263
+ readonly name = "InvalidTokenAdminRegistryInputsZeroAddress"
264
+ readonly msg = "New Admin can not be zero address"
265
+
266
+ constructor(readonly logs?: string[]) {
267
+ super("7021: New Admin can not be zero address")
268
+ }
269
+ }
270
+
271
+ export class InvalidTokenAdminRegistryProposedAdmin extends Error {
272
+ static readonly code = 7022
273
+ readonly code = 7022
274
+ readonly name = "InvalidTokenAdminRegistryProposedAdmin"
275
+ readonly msg = "An already owned registry can not be proposed"
276
+
277
+ constructor(readonly logs?: string[]) {
278
+ super("7022: An already owned registry can not be proposed")
279
+ }
280
+ }
281
+
282
+ export class SenderNotAllowed extends Error {
283
+ static readonly code = 7023
284
+ readonly code = 7023
285
+ readonly name = "SenderNotAllowed"
286
+ readonly msg = "Sender not allowed for that destination chain"
287
+
288
+ constructor(readonly logs?: string[]) {
289
+ super("7023: Sender not allowed for that destination chain")
290
+ }
291
+ }
292
+
293
+ export class InvalidCodeVersion extends Error {
294
+ static readonly code = 7024
295
+ readonly code = 7024
296
+ readonly name = "InvalidCodeVersion"
297
+ readonly msg = "Invalid code version"
298
+
299
+ constructor(readonly logs?: string[]) {
300
+ super("7024: Invalid code version")
301
+ }
302
+ }
303
+
304
+ export class InvalidCcipVersionRollback extends Error {
305
+ static readonly code = 7025
306
+ readonly code = 7025
307
+ readonly name = "InvalidCcipVersionRollback"
308
+ readonly msg =
309
+ "Invalid rollback attempt on the CCIP version of the onramp to the destination chain"
310
+
311
+ constructor(readonly logs?: string[]) {
312
+ super(
313
+ "7025: Invalid rollback attempt on the CCIP version of the onramp to the destination chain"
314
+ )
315
+ }
316
+ }
317
+
318
+ export function fromCode(code: number, logs?: string[]): CustomError | null {
319
+ switch (code) {
320
+ case 7000:
321
+ return new Unauthorized(logs)
322
+ case 7001:
323
+ return new InvalidRMNRemoteAddress(logs)
324
+ case 7002:
325
+ return new InvalidInputsMint(logs)
326
+ case 7003:
327
+ return new InvalidVersion(logs)
328
+ case 7004:
329
+ return new FeeTokenMismatch(logs)
330
+ case 7005:
331
+ return new RedundantOwnerProposal(logs)
332
+ case 7006:
333
+ return new ReachedMaxSequenceNumber(logs)
334
+ case 7007:
335
+ return new InvalidInputsTokenIndices(logs)
336
+ case 7008:
337
+ return new InvalidInputsPoolAccounts(logs)
338
+ case 7009:
339
+ return new InvalidInputsTokenAccounts(logs)
340
+ case 7010:
341
+ return new InvalidInputsTokenAdminRegistryAccounts(logs)
342
+ case 7011:
343
+ return new InvalidInputsLookupTableAccounts(logs)
344
+ case 7012:
345
+ return new InvalidInputsLookupTableAccountWritable(logs)
346
+ case 7013:
347
+ return new InvalidInputsTokenAmount(logs)
348
+ case 7014:
349
+ return new InvalidInputsTransferAllAmount(logs)
350
+ case 7015:
351
+ return new InvalidInputsAtaAddress(logs)
352
+ case 7016:
353
+ return new InvalidInputsAtaWritable(logs)
354
+ case 7017:
355
+ return new InvalidInputsChainSelector(logs)
356
+ case 7018:
357
+ return new InsufficientLamports(logs)
358
+ case 7019:
359
+ return new InsufficientFunds(logs)
360
+ case 7020:
361
+ return new SourceTokenDataTooLarge(logs)
362
+ case 7021:
363
+ return new InvalidTokenAdminRegistryInputsZeroAddress(logs)
364
+ case 7022:
365
+ return new InvalidTokenAdminRegistryProposedAdmin(logs)
366
+ case 7023:
367
+ return new SenderNotAllowed(logs)
368
+ case 7024:
369
+ return new InvalidCodeVersion(logs)
370
+ case 7025:
371
+ return new InvalidCcipVersionRollback(logs)
372
+ }
373
+
374
+ return null
375
+ }
@@ -0,0 +1,62 @@
1
+ import { PublicKey } from "@solana/web3.js"
2
+ import { PROGRAM_ID } from "../programId"
3
+ import * as anchor from "./anchor"
4
+ import * as custom from "./custom"
5
+
6
+ export function fromCode(
7
+ code: number,
8
+ logs?: string[]
9
+ ): custom.CustomError | anchor.AnchorError | null {
10
+ return code >= 6000
11
+ ? custom.fromCode(code, logs)
12
+ : anchor.fromCode(code, logs)
13
+ }
14
+
15
+ function hasOwnProperty<X extends object, Y extends PropertyKey>(
16
+ obj: X,
17
+ prop: Y
18
+ ): obj is X & Record<Y, unknown> {
19
+ return Object.hasOwnProperty.call(obj, prop)
20
+ }
21
+
22
+ const errorRe = /Program (\w+) failed: custom program error: (\w+)/
23
+
24
+ export function fromTxError(
25
+ err: unknown,
26
+ programId: PublicKey = PROGRAM_ID
27
+ ): custom.CustomError | anchor.AnchorError | null {
28
+ if (
29
+ typeof err !== "object" ||
30
+ err === null ||
31
+ !hasOwnProperty(err, "logs") ||
32
+ !Array.isArray(err.logs)
33
+ ) {
34
+ return null
35
+ }
36
+
37
+ let firstMatch: RegExpExecArray | null = null
38
+ for (const logLine of err.logs) {
39
+ firstMatch = errorRe.exec(logLine)
40
+ if (firstMatch !== null) {
41
+ break
42
+ }
43
+ }
44
+
45
+ if (firstMatch === null) {
46
+ return null
47
+ }
48
+
49
+ const [programIdRaw, codeRaw] = firstMatch.slice(1)
50
+ if (programIdRaw !== programId.toString()) {
51
+ return null
52
+ }
53
+
54
+ let errorCode: number
55
+ try {
56
+ errorCode = parseInt(codeRaw, 16)
57
+ } catch (parseErr) {
58
+ return null
59
+ }
60
+
61
+ return fromCode(errorCode, err.logs)
62
+ }
@@ -0,0 +1,112 @@
1
+ import { TransactionInstruction, PublicKey, AccountMeta } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
2
+ import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars
3
+ import * as borsh from "@coral-xyz/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
4
+ import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
5
+ import { PROGRAM_ID } from "../programId"
6
+
7
+ export interface CcipSendArgs {
8
+ destChainSelector: BN
9
+ message: types.SVM2AnyMessageFields
10
+ tokenIndexes: Uint8Array
11
+ }
12
+
13
+ export interface CcipSendAccounts {
14
+ config: PublicKey
15
+ destChainState: PublicKey
16
+ nonce: PublicKey
17
+ authority: PublicKey
18
+ systemProgram: PublicKey
19
+ feeTokenProgram: PublicKey
20
+ feeTokenMint: PublicKey
21
+ /** If paying with native SOL, this must be the zero address. */
22
+ feeTokenUserAssociatedAccount: PublicKey
23
+ feeTokenReceiver: PublicKey
24
+ feeBillingSigner: PublicKey
25
+ feeQuoter: PublicKey
26
+ feeQuoterConfig: PublicKey
27
+ feeQuoterDestChain: PublicKey
28
+ feeQuoterBillingTokenConfig: PublicKey
29
+ feeQuoterLinkTokenConfig: PublicKey
30
+ rmnRemote: PublicKey
31
+ rmnRemoteCurses: PublicKey
32
+ rmnRemoteConfig: PublicKey
33
+ }
34
+
35
+ export const layout = borsh.struct([
36
+ borsh.u64("destChainSelector"),
37
+ types.SVM2AnyMessage.layout("message"),
38
+ borsh.vecU8("tokenIndexes"),
39
+ ])
40
+
41
+ /**
42
+ * On Ramp Flow //
43
+ * Sends a message to the destination chain.
44
+ *
45
+ * Request a message to be sent to the destination chain.
46
+ * The method name needs to be ccip_send with Anchor encoding.
47
+ * This function is called by the CCIP Sender Contract (or final user) to send a message to the CCIP Router.
48
+ * The message will be sent to the receiver on the destination chain selector.
49
+ * This message emits the event CCIPMessageSent with all the necessary data to be retrieved by the OffChain Code
50
+ *
51
+ * # Arguments
52
+ *
53
+ * * `ctx` - The context containing the accounts required for sending the message.
54
+ * * `dest_chain_selector` - The chain selector for the destination chain.
55
+ * * `message` - The message to be sent. The size limit of data is 256 bytes.
56
+ * * `token_indexes` - Indices into the remaining accounts vector where the subslice for a token begins.
57
+ */
58
+ export function ccipSend(
59
+ args: CcipSendArgs,
60
+ accounts: CcipSendAccounts,
61
+ programId: PublicKey = PROGRAM_ID
62
+ ) {
63
+ const keys: Array<AccountMeta> = [
64
+ { pubkey: accounts.config, isSigner: false, isWritable: false },
65
+ { pubkey: accounts.destChainState, isSigner: false, isWritable: true },
66
+ { pubkey: accounts.nonce, isSigner: false, isWritable: true },
67
+ { pubkey: accounts.authority, isSigner: true, isWritable: true },
68
+ { pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
69
+ { pubkey: accounts.feeTokenProgram, isSigner: false, isWritable: false },
70
+ { pubkey: accounts.feeTokenMint, isSigner: false, isWritable: false },
71
+ {
72
+ pubkey: accounts.feeTokenUserAssociatedAccount,
73
+ isSigner: false,
74
+ isWritable: false,
75
+ },
76
+ { pubkey: accounts.feeTokenReceiver, isSigner: false, isWritable: true },
77
+ { pubkey: accounts.feeBillingSigner, isSigner: false, isWritable: false },
78
+ { pubkey: accounts.feeQuoter, isSigner: false, isWritable: false },
79
+ { pubkey: accounts.feeQuoterConfig, isSigner: false, isWritable: false },
80
+ { pubkey: accounts.feeQuoterDestChain, isSigner: false, isWritable: false },
81
+ {
82
+ pubkey: accounts.feeQuoterBillingTokenConfig,
83
+ isSigner: false,
84
+ isWritable: false,
85
+ },
86
+ {
87
+ pubkey: accounts.feeQuoterLinkTokenConfig,
88
+ isSigner: false,
89
+ isWritable: false,
90
+ },
91
+ { pubkey: accounts.rmnRemote, isSigner: false, isWritable: false },
92
+ { pubkey: accounts.rmnRemoteCurses, isSigner: false, isWritable: false },
93
+ { pubkey: accounts.rmnRemoteConfig, isSigner: false, isWritable: false },
94
+ ]
95
+ const identifier = Buffer.from([108, 216, 134, 191, 249, 234, 33, 84])
96
+ const buffer = Buffer.alloc(1000)
97
+ const len = layout.encode(
98
+ {
99
+ destChainSelector: args.destChainSelector,
100
+ message: types.SVM2AnyMessage.toEncodable(args.message),
101
+ tokenIndexes: Buffer.from(
102
+ args.tokenIndexes.buffer,
103
+ args.tokenIndexes.byteOffset,
104
+ args.tokenIndexes.length
105
+ ),
106
+ },
107
+ buffer
108
+ )
109
+ const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
110
+ const ix = new TransactionInstruction({ keys, programId, data })
111
+ return ix
112
+ }
@@ -0,0 +1,73 @@
1
+ import { TransactionInstruction, PublicKey, AccountMeta } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
2
+ import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars
3
+ import * as borsh from "@coral-xyz/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
4
+ import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
5
+ import { PROGRAM_ID } from "../programId"
6
+
7
+ export interface GetFeeArgs {
8
+ destChainSelector: BN
9
+ message: types.SVM2AnyMessageFields
10
+ }
11
+
12
+ export interface GetFeeAccounts {
13
+ config: PublicKey
14
+ destChainState: PublicKey
15
+ feeQuoter: PublicKey
16
+ feeQuoterConfig: PublicKey
17
+ feeQuoterDestChain: PublicKey
18
+ feeQuoterBillingTokenConfig: PublicKey
19
+ feeQuoterLinkTokenConfig: PublicKey
20
+ }
21
+
22
+ export const layout = borsh.struct([
23
+ borsh.u64("destChainSelector"),
24
+ types.SVM2AnyMessage.layout("message"),
25
+ ])
26
+
27
+ /**
28
+ * Queries the onramp for the fee required to send a message.
29
+ *
30
+ * This call is permissionless. Note it does not verify whether there's a curse active
31
+ * in order to avoid the RMN CPI overhead.
32
+ *
33
+ * # Arguments
34
+ *
35
+ * * `ctx` - The context containing the accounts required for obtaining the message fee.
36
+ * * `dest_chain_selector` - The chain selector for the destination chain.
37
+ * * `message` - The message to be sent. The size limit of data is 256 bytes.
38
+ */
39
+ export function getFee(
40
+ args: GetFeeArgs,
41
+ accounts: GetFeeAccounts,
42
+ programId: PublicKey = PROGRAM_ID
43
+ ) {
44
+ const keys: Array<AccountMeta> = [
45
+ { pubkey: accounts.config, isSigner: false, isWritable: false },
46
+ { pubkey: accounts.destChainState, isSigner: false, isWritable: false },
47
+ { pubkey: accounts.feeQuoter, isSigner: false, isWritable: false },
48
+ { pubkey: accounts.feeQuoterConfig, isSigner: false, isWritable: false },
49
+ { pubkey: accounts.feeQuoterDestChain, isSigner: false, isWritable: false },
50
+ {
51
+ pubkey: accounts.feeQuoterBillingTokenConfig,
52
+ isSigner: false,
53
+ isWritable: false,
54
+ },
55
+ {
56
+ pubkey: accounts.feeQuoterLinkTokenConfig,
57
+ isSigner: false,
58
+ isWritable: false,
59
+ },
60
+ ]
61
+ const identifier = Buffer.from([115, 195, 235, 161, 25, 219, 60, 29])
62
+ const buffer = Buffer.alloc(1000)
63
+ const len = layout.encode(
64
+ {
65
+ destChainSelector: args.destChainSelector,
66
+ message: types.SVM2AnyMessage.toEncodable(args.message),
67
+ },
68
+ buffer
69
+ )
70
+ const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
71
+ const ix = new TransactionInstruction({ keys, programId, data })
72
+ return ix
73
+ }
@@ -0,0 +1,4 @@
1
+ export { ccipSend } from "./ccipSend";
2
+ export type { CcipSendArgs, CcipSendAccounts } from "./ccipSend";
3
+ export { getFee } from "./getFee";
4
+ export type { GetFeeArgs, GetFeeAccounts } from "./getFee";
@@ -0,0 +1,6 @@
1
+ import { PublicKey } from "@solana/web3.js"
2
+
3
+ // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
4
+ export const PROGRAM_ID: PublicKey = new PublicKey(
5
+ "Ccip8ZTcM2qHjVt8FYHtuCAqjc637yLKnsJ5q5r2e6eL"
6
+ )