@xswap-link/sdk 0.10.7 → 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 (73) hide show
  1. package/.eslintrc.json +10 -1
  2. package/.github/workflows/publish.yml +10 -10
  3. package/CHANGELOG.md +12 -0
  4. package/dist/index.global.js +331 -331
  5. package/dist/index.js +9 -9
  6. package/dist/index.mjs +9 -9
  7. package/package.json +6 -3
  8. package/src/components/Swap/SwapView/ConfirmationView/TxOverview/index.tsx +106 -9
  9. package/src/components/Swap/SwapView/SwapButton/index.tsx +11 -11
  10. package/src/components/TxDataCard/TxDataCardUI/index.tsx +12 -18
  11. package/src/components/TxDataCard/index.tsx +6 -2
  12. package/src/constants/index.ts +19 -2
  13. package/src/context/SwapProvider.tsx +7 -3
  14. package/src/services/api.ts +1 -0
  15. package/src/services/solana/jupiter/extract-swap-data.ts +6 -7
  16. package/src/services/svm/README.md +483 -0
  17. package/src/services/svm/bindings/accounts/AllowedOfframp.ts +73 -0
  18. package/src/services/svm/bindings/accounts/Config.ts +153 -0
  19. package/src/services/svm/bindings/accounts/DestChain.ts +113 -0
  20. package/src/services/svm/bindings/accounts/Nonce.ts +97 -0
  21. package/src/services/svm/bindings/accounts/index.ts +15 -0
  22. package/src/services/svm/bindings/accounts/tokenAdminRegistry.ts +128 -0
  23. package/src/services/svm/bindings/errors/anchor.ts +773 -0
  24. package/src/services/svm/bindings/errors/custom.ts +375 -0
  25. package/src/services/svm/bindings/errors/index.ts +62 -0
  26. package/src/services/svm/bindings/instructions/ccipSend.ts +112 -0
  27. package/src/services/svm/bindings/instructions/getFee.ts +73 -0
  28. package/src/services/svm/bindings/instructions/index.ts +4 -0
  29. package/src/services/svm/bindings/programId.ts +6 -0
  30. package/src/services/svm/bindings/types/BaseChain.ts +92 -0
  31. package/src/services/svm/bindings/types/BaseConfig.ts +184 -0
  32. package/src/services/svm/bindings/types/CodeVersion.ts +88 -0
  33. package/src/services/svm/bindings/types/CrossChainAmount.ts +53 -0
  34. package/src/services/svm/bindings/types/DestChainConfig.ts +76 -0
  35. package/src/services/svm/bindings/types/DestChainState.ts +76 -0
  36. package/src/services/svm/bindings/types/GetFeeResult.ts +72 -0
  37. package/src/services/svm/bindings/types/LockOrBurnInV1.ts +102 -0
  38. package/src/services/svm/bindings/types/LockOrBurnOutV1.ts +79 -0
  39. package/src/services/svm/bindings/types/RampMessageHeader.ts +94 -0
  40. package/src/services/svm/bindings/types/RateLimitConfig.ts +72 -0
  41. package/src/services/svm/bindings/types/RateLimitTokenBucket.ts +76 -0
  42. package/src/services/svm/bindings/types/ReleaseOrMintInV1.ts +156 -0
  43. package/src/services/svm/bindings/types/ReleaseOrMintOutV1.ts +53 -0
  44. package/src/services/svm/bindings/types/RemoteAddress.ts +61 -0
  45. package/src/services/svm/bindings/types/RemoteConfig.ts +86 -0
  46. package/src/services/svm/bindings/types/RestoreOnAction.ts +120 -0
  47. package/src/services/svm/bindings/types/SVM2AnyMessage.ts +128 -0
  48. package/src/services/svm/bindings/types/SVM2AnyRampMessage.ts +166 -0
  49. package/src/services/svm/bindings/types/SVM2AnyTokenTransfer.ts +118 -0
  50. package/src/services/svm/bindings/types/SVMTokenAmount.ts +64 -0
  51. package/src/services/svm/bindings/types/index.ts +78 -0
  52. package/src/services/svm/core/client/accounts.ts +97 -0
  53. package/src/services/svm/core/client/events.ts +95 -0
  54. package/src/services/svm/core/client/fee.ts +279 -0
  55. package/src/services/svm/core/client/index.ts +150 -0
  56. package/src/services/svm/core/client/send.ts +607 -0
  57. package/src/services/svm/core/client/utils.ts +131 -0
  58. package/src/services/svm/core/models.ts +236 -0
  59. package/src/services/svm/index.ts +32 -0
  60. package/src/services/svm/utils/conversion.ts +62 -0
  61. package/src/services/svm/utils/errors.ts +51 -0
  62. package/src/services/svm/utils/keypair.ts +19 -0
  63. package/src/services/svm/utils/logger.ts +171 -0
  64. package/src/services/svm/utils/pdas/common.ts +15 -0
  65. package/src/services/svm/utils/pdas/feeQuoter.ts +68 -0
  66. package/src/services/svm/utils/pdas/index.ts +12 -0
  67. package/src/services/svm/utils/pdas/receiver.ts +58 -0
  68. package/src/services/svm/utils/pdas/rmnRemote.ts +23 -0
  69. package/src/services/svm/utils/pdas/router.ts +328 -0
  70. package/src/services/svm/utils/pdas/tokenpool.ts +161 -0
  71. package/src/services/svm/utils/transaction.ts +132 -0
  72. package/src/utils/validation.ts +7 -3
  73. package/tsconfig.json +2 -1
@@ -0,0 +1,483 @@
1
+ # CCIP Solana SDK
2
+
3
+ A TypeScript SDK for interacting with the Chainlink CCIP protocol on Solana.
4
+
5
+ ## Installation
6
+
7
+ This SDK is part of the CCIP library and is not published as a standalone npm package. To use it:
8
+
9
+ 1. Clone this repository
10
+ 2. Import the modules directly from the codebase
11
+
12
+ ```typescript
13
+ // Example import from local codebase
14
+ import { CCIPClient } from "../path/to/ccip-lib/svm";
15
+ ```
16
+
17
+ ## Key Features
18
+
19
+ - Fee calculation for CCIP messages with support for various token types
20
+ - Message sending with transaction monitoring and compute budget management
21
+ - Message ID extraction from transaction logs with event parsing
22
+ - ExtraArgs generation for cross-chain messages with customizable gas limits
23
+ - Comprehensive PDA utilities for all CCIP account types
24
+ - Anchor-generated bindings for all CCIP accounts and instructions
25
+ - Flexible configuration management with dependency injection
26
+ - Structured logging throughout the SDK
27
+ - Token pool management (burn-mint pools) for cross-chain token transfers
28
+
29
+ ## Architecture
30
+
31
+ The SDK follows a modular architecture with clear separation of concerns:
32
+
33
+ ### Core Components
34
+
35
+ - **CCIPClient**: Main entry point for SDK functionality (fee calculation, message sending, token pool access)
36
+ - **CCIPAccountReader**: Handles fetching and decoding on-chain CCIP accounts
37
+ - **Models**: Type definitions shared across all components
38
+
39
+ ### Token Pools
40
+
41
+ - **TokenPoolClient**: Abstract interface for token pool operations
42
+ - **BurnMintTokenPoolClient**: Implementation for burn-mint token pools
43
+ - **TokenPoolFactory**: Factory for creating and detecting token pool types
44
+
45
+ ### Bindings
46
+
47
+ - **Accounts**: Auto-generated Anchor bindings for all on-chain account structs
48
+ - **Instructions**: Auto-generated Anchor bindings for all on-chain instructions
49
+ - **Types**: Type definitions for core CCIP protocol data structures
50
+
51
+ ### Utilities
52
+
53
+ - **PDAs**: Comprehensive utilities for deriving all program-derived addresses
54
+ - **Logger**: Structured logging with configurable log levels
55
+ - **Conversion**: Helper functions for data type conversions
56
+ - **Error Handling**: Standardized error types and handling
57
+
58
+ ## Usage
59
+
60
+ ### Basic Usage
61
+
62
+ ```typescript
63
+ import {
64
+ CCIPClient,
65
+ CCIPSendRequest,
66
+ ExtraArgsOptions,
67
+ CCIPContext,
68
+ CCIPProvider,
69
+ CCIPCoreConfig,
70
+ LogLevel,
71
+ createLogger,
72
+ } from "../path/to/ccip-lib/svm";
73
+ import { PublicKey, Connection, Keypair } from "@solana/web3.js";
74
+ import { BN } from "@coral-xyz/anchor";
75
+
76
+ // Create a provider (application responsibility)
77
+ const connection = new Connection("https://api.devnet.solana.com", "confirmed");
78
+ const keypair = Keypair.fromSecretKey(/* your secret key */);
79
+
80
+ const provider: CCIPProvider = {
81
+ connection,
82
+ wallet: keypair,
83
+ getAddress(): PublicKey {
84
+ return keypair.publicKey;
85
+ },
86
+ async signTransaction(tx) {
87
+ if (tx instanceof VersionedTransaction) {
88
+ tx.sign([keypair]);
89
+ } else {
90
+ tx.partialSign(keypair);
91
+ }
92
+ return tx;
93
+ },
94
+ };
95
+
96
+ // Create configuration (application responsibility)
97
+ const config: CCIPCoreConfig = {
98
+ ccipRouterProgramId: new PublicKey(
99
+ "Ccip8ZTcM2qHjVt8FYHtuCAqjc637yLKnsJ5q5r2e6eL"
100
+ ),
101
+ feeQuoterProgramId: new PublicKey(
102
+ "FeeQhewH1cd6ZyHqhfMiKAQntgzPT6bWwK26cJ5qSFo6"
103
+ ),
104
+ rmnRemoteProgramId: new PublicKey(
105
+ "RmnAZiCJdaYtwR1f634Ba7yNJXuK3pS6kHuX4FgNgX8"
106
+ ),
107
+ linkTokenMint: new PublicKey("D3HCrigxfvScYyokPC1YGpNgqyheVMVwbgP7XPywvEdc"),
108
+ tokenMint: new PublicKey("7AC59PVvR64EoMnLX45FHnJAYzPsxdViyYBsaGEQPFvh"),
109
+ nativeSol: PublicKey.default,
110
+ systemProgramId: new PublicKey("11111111111111111111111111111111"),
111
+ ethereumSepoliaSelector: BigInt("16015286601757825753"),
112
+ programId: new PublicKey("52XvWQKuZHRjnR7qHsEGE532jqgQ3MBiBMgVkBowP1LD"),
113
+ };
114
+
115
+ // Create context with provider and config
116
+ const context: CCIPContext = {
117
+ provider,
118
+ config,
119
+ logger: createLogger("my-app", { level: LogLevel.INFO }),
120
+ };
121
+
122
+ // Create CCIPClient with the context
123
+ const client = new CCIPClient(context);
124
+
125
+ // Create extraArgs configuration
126
+ const extraArgsConfig: ExtraArgsOptions = {
127
+ gasLimit: 200000,
128
+ allowOutOfOrderExecution: true,
129
+ };
130
+
131
+ // Generate the extraArgs buffer
132
+ const extraArgs = client.createExtraArgs(extraArgsConfig);
133
+
134
+ // Create a CCIP send request
135
+ const sendRequest: CCIPSendRequest = {
136
+ destChainSelector: new BN("16015286601757825753"),
137
+ receiver: Buffer.from(
138
+ "0x9d087fC03ae39b088326b67fA3C788236645b717".slice(2),
139
+ "hex"
140
+ ),
141
+ data: Buffer.alloc(0), // Empty data for token transfer only
142
+ tokenAmounts: [
143
+ {
144
+ token: new PublicKey("7AC59PVvR64EoMnLX45FHnJAYzPsxdViyYBsaGEQPFvh"),
145
+ amount: new BN(10000000), // 0.01 tokens with 9 decimals
146
+ },
147
+ ],
148
+ feeToken: PublicKey.default, // Use native SOL
149
+ extraArgs: extraArgs,
150
+ };
151
+
152
+ // Calculate fee first (optional)
153
+ const feeRequest = {
154
+ destChainSelector: sendRequest.destChainSelector,
155
+ message: {
156
+ receiver: sendRequest.receiver,
157
+ data: sendRequest.data,
158
+ tokenAmounts: sendRequest.tokenAmounts,
159
+ feeToken: sendRequest.feeToken,
160
+ extraArgs: extraArgs,
161
+ },
162
+ };
163
+
164
+ const feeResult = await client.getFee(feeRequest);
165
+ console.log(`Estimated fee: ${feeResult.amount.toString()}`);
166
+
167
+ // Send the message and get message ID
168
+ const result = await client.sendWithMessageId(sendRequest);
169
+ console.log(`Message sent! Transaction: ${result.txSignature}`);
170
+ console.log(`Message ID: ${result.messageId}`);
171
+ console.log(`Destination Chain Selector: ${result.destinationChainSelector}`);
172
+ console.log(`Sequence Number: ${result.sequenceNumber}`);
173
+ ```
174
+
175
+ ### Using with Wallet Adapters
176
+
177
+ You can easily integrate with Solana wallet adapters:
178
+
179
+ ```typescript
180
+ import {
181
+ CCIPClient,
182
+ CCIPContext,
183
+ CCIPProvider,
184
+ CCIPCoreConfig,
185
+ } from "../path/to/ccip-lib/svm";
186
+ import {
187
+ Connection,
188
+ PublicKey,
189
+ Transaction,
190
+ VersionedTransaction,
191
+ } from "@solana/web3.js";
192
+ import { useWallet } from "@solana/wallet-adapter-react";
193
+
194
+ // In your React component
195
+ function MyComponent() {
196
+ const { publicKey, signTransaction } = useWallet();
197
+ const connection = new Connection("https://api.devnet.solana.com");
198
+
199
+ // Create provider from wallet adapter
200
+ const provider: CCIPProvider = {
201
+ connection,
202
+ wallet: null, // Not used directly with wallet adapter
203
+ getAddress(): PublicKey {
204
+ return publicKey;
205
+ },
206
+ async signTransaction(tx: Transaction | VersionedTransaction) {
207
+ return await signTransaction(tx);
208
+ },
209
+ };
210
+
211
+ // Get your config from application
212
+ const config: CCIPCoreConfig = {
213
+ // ...your config properties
214
+ };
215
+
216
+ // Create context
217
+ const context: CCIPContext = {
218
+ provider,
219
+ config,
220
+ };
221
+
222
+ // Create client
223
+ const client = new CCIPClient(context);
224
+
225
+ // Use client...
226
+ }
227
+ ```
228
+
229
+ ### ExtraArgs Configuration
230
+
231
+ The SDK supports creating properly formatted extraArgs for CCIP messages:
232
+
233
+ ```typescript
234
+ // Configure extraArgs with options
235
+ const extraArgs = client.createExtraArgs({
236
+ gasLimit: 200000, // Gas limit for execution on destination chain
237
+ allowOutOfOrderExecution: true, // Whether to allow out-of-order execution
238
+ });
239
+
240
+ // Or use default values
241
+ const defaultExtraArgs = client.createExtraArgs();
242
+ ```
243
+
244
+ ### Using the Account Reader
245
+
246
+ The CCIPAccountReader provides convenient methods to fetch and decode on-chain accounts:
247
+
248
+ ```typescript
249
+ // Get the account reader from the client
250
+ const accountReader = client.getAccountReader();
251
+
252
+ // Fetch token admin registry for a token
253
+ const tokenRegistry = await accountReader.getTokenAdminRegistry(tokenMint);
254
+
255
+ // Fetch CCIP configuration
256
+ const config = await accountReader.getConfig();
257
+
258
+ // Fetch destination chain state
259
+ const destChainState = await accountReader.getDestChainState(destChainSelector);
260
+ ```
261
+
262
+ ## PDA Utilities
263
+
264
+ The SDK provides comprehensive utility functions for calculating Program Derived Addresses (PDAs) used throughout the CCIP protocol.
265
+
266
+ ### Token Pools Signer PDAs
267
+
268
+ When delegating token authority for CCIP cross-chain transfers, it's crucial to understand that there are two different types of PDA signers:
269
+
270
+ 1. `feeBillingSignerPDA` - Used for fee payments (derived with the `fee_billing_signer` seed)
271
+ 2. `tokenPoolsSignerPDA` - Used for token transfers (derived with the `external_token_pools_signer` seed)
272
+
273
+ #### Important Note About Token Pool Signers
274
+
275
+ The token pool signer PDA is more complex than it initially appears. In the CCIP protocol, the actual PDA used for token transfers is derived using **both**:
276
+
277
+ 1. The `external_token_pools_signer` seed
278
+ 2. The pool program ID (which is specific to each token)
279
+
280
+ The pool program ID is stored in a lookup table that is part of the token admin registry for each token. This means a simple `findExternalTokenPoolsSignerPDA` function that uses only the seed is **not sufficient** for accurate delegation.
281
+
282
+ #### PDA Functions
283
+
284
+ To address this complexity, the SDK provides several functions:
285
+
286
+ ```typescript
287
+ // Basic function - not sufficient for token transfers
288
+ findExternalTokenPoolsSignerPDA(programId: PublicKey): [PublicKey, number]
289
+
290
+ // Recommended - dynamically finds the correct token pool signer PDA
291
+ findDynamicTokenPoolsSignerPDA(
292
+ mint: PublicKey,
293
+ routerProgramId: PublicKey,
294
+ connection: Connection
295
+ ): Promise<[PublicKey, number]>
296
+
297
+ // Alternative using CCIPAccountReader
298
+ findTokenPoolsSignerWithAccountReader(
299
+ mint: PublicKey,
300
+ routerProgramId: PublicKey,
301
+ accountReader: CCIPAccountReader,
302
+ connection: Connection
303
+ ): Promise<[PublicKey, number]>
304
+ ```
305
+
306
+ ### Other Important PDAs
307
+
308
+ The SDK provides utilities for all PDAs used in the CCIP protocol:
309
+
310
+ ```typescript
311
+ // Router configuration PDA
312
+ findConfigPDA(programId: PublicKey): [PublicKey, number]
313
+
314
+ // Fee billing signer PDA (for fee payments)
315
+ findFeeBillingSignerPDA(programId: PublicKey): [PublicKey, number]
316
+
317
+ // Token admin registry PDA
318
+ findTokenAdminRegistryPDA(mint: PublicKey, programId: PublicKey): [PublicKey, number]
319
+
320
+ // Destination chain state PDA
321
+ findDestChainStatePDA(chainSelector: bigint, programId: PublicKey): [PublicKey, number]
322
+
323
+ // Nonce PDA
324
+ findNoncePDA(chainSelector: bigint, authority: PublicKey, programId: PublicKey): [PublicKey, number]
325
+
326
+ // Token pool chain config PDA
327
+ findTokenPoolChainConfigPDA(
328
+ chainSelector: bigint,
329
+ tokenMint: PublicKey,
330
+ programId: PublicKey
331
+ ): [PublicKey, number]
332
+ ```
333
+
334
+ #### Usage for Token Delegation
335
+
336
+ When delegating token authority to the CCIP protocol, you should:
337
+
338
+ 1. Use `findFeeBillingSignerPDA` for fee token delegation (e.g., SOL)
339
+ 2. Use `findDynamicTokenPoolsSignerPDA` for token transfer delegation (e.g., BnM, LINK)
340
+
341
+ ```typescript
342
+ // For fee token delegation (e.g., SOL)
343
+ const [feeBillingSigner] = findFeeBillingSignerPDA(routerProgramId);
344
+
345
+ // For token transfer delegation (e.g., BnM, LINK)
346
+ const [tokenPoolsSigner] = await findDynamicTokenPoolsSignerPDA(
347
+ tokenMint,
348
+ routerProgramId,
349
+ connection
350
+ );
351
+ ```
352
+
353
+ ## Token Pool Support
354
+
355
+ The SDK provides support for interacting with different types of token pools used by CCIP for cross-chain transfers.
356
+
357
+ ### Token Pool Types
358
+
359
+ Currently, the SDK supports the following pool types:
360
+
361
+ - **Burn-Mint Pools**: Tokens are burned on the source chain and minted on the destination chain.
362
+
363
+ ### Using Token Pools
364
+
365
+ Token pools can be accessed through the `CCIPClient`:
366
+
367
+ ```typescript
368
+ // Get a burn-mint token pool client
369
+ const burnMintPool = client.getTokenPoolClient(TokenPoolType.BURN_MINT);
370
+
371
+ // Or auto-detect the pool type for a specific token mint
372
+ const pool = await client.getTokenPoolClientForMint(tokenMint);
373
+
374
+ // Create a new pool for a token
375
+ const txSignature = await pool.createPool(tokenMint);
376
+
377
+ // Configure a chain for cross-chain transfers
378
+ const chainConfig = {
379
+ enabled: true,
380
+ maxTokensPerMessage: new BN(1000000000), // 1 token with 9 decimals
381
+ feeBps: 10 // 0.1% fee
382
+ };
383
+ await pool.configureChain(tokenMint, destinationChainSelector, chainConfig);
384
+
385
+ // Set rate limits for a token
386
+ await pool.setRateLimit(
387
+ tokenMint,
388
+ new BN(1000000000), // Capacity: 1 token with 9 decimals
389
+ new BN(100000000) // Rate: 0.1 tokens per second
390
+ );
391
+
392
+ // Transfer admin role for a token pool
393
+ await pool.transferAdminRole(tokenMint, newAdminPublicKey);
394
+ ```
395
+
396
+ ### Token Pool Factory
397
+
398
+ For advanced usage, you can use the `TokenPoolFactory` directly:
399
+
400
+ ```typescript
401
+ import { TokenPoolFactory, TokenPoolType } from "../path/to/ccip-lib/svm";
402
+
403
+ // Create a specific token pool type
404
+ const pool = TokenPoolFactory.create(TokenPoolType.BURN_MINT, context);
405
+
406
+ // Auto-detect the token pool type for a mint
407
+ const poolType = await TokenPoolFactory.detectPoolType(tokenMint, context);
408
+ const pool = TokenPoolFactory.create(poolType, context);
409
+ ```
410
+
411
+ ### PDA Utilities for Token Pools
412
+
413
+ The SDK provides functions to derive all program-derived addresses used in token pools:
414
+
415
+ ```typescript
416
+ import {
417
+ findBurnMintPoolConfigPDA,
418
+ findBurnMintPoolChainConfigPDA,
419
+ findRateLimitPDA
420
+ } from "../path/to/ccip-lib/svm";
421
+
422
+ // Get the pool config PDA
423
+ const [poolConfigPDA] = findBurnMintPoolConfigPDA(tokenMint, burnMintPoolProgramId);
424
+
425
+ // Get the chain config PDA
426
+ const [chainConfigPDA] = findBurnMintPoolChainConfigPDA(
427
+ chainSelector,
428
+ tokenMint,
429
+ burnMintPoolProgramId
430
+ );
431
+
432
+ // Get the rate limit PDA
433
+ const [rateLimitPDA] = findRateLimitPDA(tokenMint, burnMintPoolProgramId);
434
+ ```
435
+
436
+ ## Error Handling
437
+
438
+ The SDK uses standardized error handling with custom error types:
439
+
440
+ ```typescript
441
+ import {
442
+ CCIPError,
443
+ CCIPTransactionError,
444
+ CCIPAccountError,
445
+ } from "../path/to/ccip-lib/svm";
446
+
447
+ try {
448
+ await client.sendWithMessageId(sendRequest);
449
+ } catch (error) {
450
+ if (error instanceof CCIPTransactionError) {
451
+ console.error(`Transaction failed: ${error.message}`, error.txSignature);
452
+ } else if (error instanceof CCIPAccountError) {
453
+ console.error(`Account error: ${error.message}`, error.account);
454
+ } else if (error instanceof CCIPError) {
455
+ console.error(`CCIP error: ${error.message}`);
456
+ } else {
457
+ console.error(`Unknown error: ${error}`);
458
+ }
459
+ }
460
+ ```
461
+
462
+ ## Logging
463
+
464
+ The SDK supports structured logging with configurable log levels:
465
+
466
+ ```typescript
467
+ import { createLogger, LogLevel } from "../path/to/ccip-lib/svm";
468
+
469
+ // Create a logger with custom configuration
470
+ const logger = createLogger("my-component", {
471
+ level: LogLevel.DEBUG,
472
+ pretty: true, // For human-readable logs
473
+ skipTimestamp: false, // Include timestamps
474
+ });
475
+
476
+ // Use the logger
477
+ logger.info("Processing request", { destination: "ethereum" });
478
+ logger.debug("Technical details", { request: sendRequest });
479
+ logger.error("Operation failed", { error });
480
+
481
+ // Change log level at runtime
482
+ logger.setLevel(LogLevel.WARN);
483
+ ```
@@ -0,0 +1,73 @@
1
+ import { PublicKey, Connection } from "@solana/web3.js"
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 AllowedOfframpFields {}
8
+
9
+ export interface AllowedOfframpJSON {}
10
+
11
+ export class AllowedOfframp {
12
+ static readonly discriminator = Buffer.from([
13
+ 247, 97, 179, 16, 207, 36, 236, 132,
14
+ ])
15
+
16
+ static readonly layout = borsh.struct([])
17
+
18
+ constructor(fields: AllowedOfframpFields) {}
19
+
20
+ static async fetch(
21
+ c: Connection,
22
+ address: PublicKey,
23
+ programId: PublicKey = PROGRAM_ID
24
+ ): Promise<AllowedOfframp | null> {
25
+ const info = await c.getAccountInfo(address)
26
+
27
+ if (info === null) {
28
+ return null
29
+ }
30
+ if (!info.owner.equals(programId)) {
31
+ throw new Error("account doesn't belong to this program")
32
+ }
33
+
34
+ return this.decode(info.data)
35
+ }
36
+
37
+ static async fetchMultiple(
38
+ c: Connection,
39
+ addresses: PublicKey[],
40
+ programId: PublicKey = PROGRAM_ID
41
+ ): Promise<Array<AllowedOfframp | null>> {
42
+ const infos = await c.getMultipleAccountsInfo(addresses)
43
+
44
+ return infos.map((info) => {
45
+ if (info === null) {
46
+ return null
47
+ }
48
+ if (!info.owner.equals(programId)) {
49
+ throw new Error("account doesn't belong to this program")
50
+ }
51
+
52
+ return this.decode(info.data)
53
+ })
54
+ }
55
+
56
+ static decode(data: Buffer): AllowedOfframp {
57
+ if (!data.slice(0, 8).equals(AllowedOfframp.discriminator)) {
58
+ throw new Error("invalid account discriminator")
59
+ }
60
+
61
+ const dec = AllowedOfframp.layout.decode(data.slice(8))
62
+
63
+ return new AllowedOfframp({})
64
+ }
65
+
66
+ toJSON(): AllowedOfframpJSON {
67
+ return {}
68
+ }
69
+
70
+ static fromJSON(obj: AllowedOfframpJSON): AllowedOfframp {
71
+ return new AllowedOfframp({})
72
+ }
73
+ }
@@ -0,0 +1,153 @@
1
+ import { PublicKey, Connection } from "@solana/web3.js"
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 ConfigFields {
8
+ version: number
9
+ defaultCodeVersion: types.CodeVersionKind
10
+ svmChainSelector: BN
11
+ owner: PublicKey
12
+ proposedOwner: PublicKey
13
+ feeQuoter: PublicKey
14
+ rmnRemote: PublicKey
15
+ linkTokenMint: PublicKey
16
+ feeAggregator: PublicKey
17
+ }
18
+
19
+ export interface ConfigJSON {
20
+ version: number
21
+ defaultCodeVersion: types.CodeVersionJSON
22
+ svmChainSelector: string
23
+ owner: string
24
+ proposedOwner: string
25
+ feeQuoter: string
26
+ rmnRemote: string
27
+ linkTokenMint: string
28
+ feeAggregator: string
29
+ }
30
+
31
+ export class Config {
32
+ readonly version: number
33
+ readonly defaultCodeVersion: types.CodeVersionKind
34
+ readonly svmChainSelector: BN
35
+ readonly owner: PublicKey
36
+ readonly proposedOwner: PublicKey
37
+ readonly feeQuoter: PublicKey
38
+ readonly rmnRemote: PublicKey
39
+ readonly linkTokenMint: PublicKey
40
+ readonly feeAggregator: PublicKey
41
+
42
+ static readonly discriminator = Buffer.from([
43
+ 155, 12, 170, 224, 30, 250, 204, 130,
44
+ ])
45
+
46
+ static readonly layout = borsh.struct([
47
+ borsh.u8("version"),
48
+ types.CodeVersion.layout("defaultCodeVersion"),
49
+ borsh.u64("svmChainSelector"),
50
+ borsh.publicKey("owner"),
51
+ borsh.publicKey("proposedOwner"),
52
+ borsh.publicKey("feeQuoter"),
53
+ borsh.publicKey("rmnRemote"),
54
+ borsh.publicKey("linkTokenMint"),
55
+ borsh.publicKey("feeAggregator"),
56
+ ])
57
+
58
+ constructor(fields: ConfigFields) {
59
+ this.version = fields.version
60
+ this.defaultCodeVersion = fields.defaultCodeVersion
61
+ this.svmChainSelector = fields.svmChainSelector
62
+ this.owner = fields.owner
63
+ this.proposedOwner = fields.proposedOwner
64
+ this.feeQuoter = fields.feeQuoter
65
+ this.rmnRemote = fields.rmnRemote
66
+ this.linkTokenMint = fields.linkTokenMint
67
+ this.feeAggregator = fields.feeAggregator
68
+ }
69
+
70
+ static async fetch(
71
+ c: Connection,
72
+ address: PublicKey,
73
+ programId: PublicKey = PROGRAM_ID
74
+ ): Promise<Config | null> {
75
+ const info = await c.getAccountInfo(address)
76
+
77
+ if (info === null) {
78
+ return null
79
+ }
80
+ if (!info.owner.equals(programId)) {
81
+ throw new Error("account doesn't belong to this program")
82
+ }
83
+
84
+ return this.decode(info.data)
85
+ }
86
+
87
+ static async fetchMultiple(
88
+ c: Connection,
89
+ addresses: PublicKey[],
90
+ programId: PublicKey = PROGRAM_ID
91
+ ): Promise<Array<Config | null>> {
92
+ const infos = await c.getMultipleAccountsInfo(addresses)
93
+
94
+ return infos.map((info) => {
95
+ if (info === null) {
96
+ return null
97
+ }
98
+ if (!info.owner.equals(programId)) {
99
+ throw new Error("account doesn't belong to this program")
100
+ }
101
+
102
+ return this.decode(info.data)
103
+ })
104
+ }
105
+
106
+ static decode(data: Buffer): Config {
107
+ if (!data.slice(0, 8).equals(Config.discriminator)) {
108
+ throw new Error("invalid account discriminator")
109
+ }
110
+
111
+ const dec = Config.layout.decode(data.slice(8))
112
+
113
+ return new Config({
114
+ version: dec.version,
115
+ defaultCodeVersion: types.CodeVersion.fromDecoded(dec.defaultCodeVersion),
116
+ svmChainSelector: dec.svmChainSelector,
117
+ owner: dec.owner,
118
+ proposedOwner: dec.proposedOwner,
119
+ feeQuoter: dec.feeQuoter,
120
+ rmnRemote: dec.rmnRemote,
121
+ linkTokenMint: dec.linkTokenMint,
122
+ feeAggregator: dec.feeAggregator,
123
+ })
124
+ }
125
+
126
+ toJSON(): ConfigJSON {
127
+ return {
128
+ version: this.version,
129
+ defaultCodeVersion: this.defaultCodeVersion.toJSON(),
130
+ svmChainSelector: this.svmChainSelector.toString(),
131
+ owner: this.owner.toString(),
132
+ proposedOwner: this.proposedOwner.toString(),
133
+ feeQuoter: this.feeQuoter.toString(),
134
+ rmnRemote: this.rmnRemote.toString(),
135
+ linkTokenMint: this.linkTokenMint.toString(),
136
+ feeAggregator: this.feeAggregator.toString(),
137
+ }
138
+ }
139
+
140
+ static fromJSON(obj: ConfigJSON): Config {
141
+ return new Config({
142
+ version: obj.version,
143
+ defaultCodeVersion: types.CodeVersion.fromJSON(obj.defaultCodeVersion),
144
+ svmChainSelector: new BN(obj.svmChainSelector),
145
+ owner: new PublicKey(obj.owner),
146
+ proposedOwner: new PublicKey(obj.proposedOwner),
147
+ feeQuoter: new PublicKey(obj.feeQuoter),
148
+ rmnRemote: new PublicKey(obj.rmnRemote),
149
+ linkTokenMint: new PublicKey(obj.linkTokenMint),
150
+ feeAggregator: new PublicKey(obj.feeAggregator),
151
+ })
152
+ }
153
+ }