@chainlink/ccip-sdk 0.91.0 → 0.92.0
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/README.md +127 -80
- package/dist/aptos/hasher.d.ts.map +1 -1
- package/dist/aptos/hasher.js +7 -6
- package/dist/aptos/hasher.js.map +1 -1
- package/dist/aptos/index.d.ts +7 -2
- package/dist/aptos/index.d.ts.map +1 -1
- package/dist/aptos/index.js +29 -20
- package/dist/aptos/index.js.map +1 -1
- package/dist/aptos/logs.d.ts +5 -3
- package/dist/aptos/logs.d.ts.map +1 -1
- package/dist/aptos/logs.js +64 -27
- package/dist/aptos/logs.js.map +1 -1
- package/dist/aptos/token.d.ts.map +1 -1
- package/dist/aptos/token.js +2 -1
- package/dist/aptos/token.js.map +1 -1
- package/dist/aptos/types.js +6 -6
- package/dist/aptos/types.js.map +1 -1
- package/dist/chain.d.ts +36 -11
- package/dist/chain.d.ts.map +1 -1
- package/dist/chain.js +34 -2
- package/dist/chain.js.map +1 -1
- package/dist/commits.d.ts +2 -3
- package/dist/commits.d.ts.map +1 -1
- package/dist/commits.js +19 -8
- package/dist/commits.js.map +1 -1
- package/dist/errors/CCIPError.d.ts +48 -0
- package/dist/errors/CCIPError.d.ts.map +1 -0
- package/dist/errors/CCIPError.js +65 -0
- package/dist/errors/CCIPError.js.map +1 -0
- package/dist/errors/codes.d.ts +120 -0
- package/dist/errors/codes.d.ts.map +1 -0
- package/dist/errors/codes.js +156 -0
- package/dist/errors/codes.js.map +1 -0
- package/dist/errors/index.d.ts +26 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +51 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/recovery.d.ts +6 -0
- package/dist/errors/recovery.d.ts.map +1 -0
- package/dist/errors/recovery.js +118 -0
- package/dist/errors/recovery.js.map +1 -0
- package/dist/errors/specialized.d.ts +637 -0
- package/dist/errors/specialized.d.ts.map +1 -0
- package/dist/errors/specialized.js +1298 -0
- package/dist/errors/specialized.js.map +1 -0
- package/dist/errors/utils.d.ts +11 -0
- package/dist/errors/utils.d.ts.map +1 -0
- package/dist/errors/utils.js +61 -0
- package/dist/errors/utils.js.map +1 -0
- package/dist/evm/abi/CommitStore_1_5.js +1 -1
- package/dist/evm/abi/LockReleaseTokenPool_1_5.js +1 -1
- package/dist/evm/abi/OffRamp_1_5.js +1 -1
- package/dist/evm/abi/OnRamp_1_5.js +1 -1
- package/dist/evm/abi/PriceRegistry_1_2.d.ts +443 -0
- package/dist/evm/abi/PriceRegistry_1_2.d.ts.map +1 -0
- package/dist/evm/abi/PriceRegistry_1_2.js +439 -0
- package/dist/evm/abi/PriceRegistry_1_2.js.map +1 -0
- package/dist/evm/const.d.ts +1 -0
- package/dist/evm/const.d.ts.map +1 -1
- package/dist/evm/const.js +2 -0
- package/dist/evm/const.js.map +1 -1
- package/dist/evm/hasher.d.ts.map +1 -1
- package/dist/evm/hasher.js +7 -6
- package/dist/evm/hasher.js.map +1 -1
- package/dist/evm/index.d.ts +9 -13
- package/dist/evm/index.d.ts.map +1 -1
- package/dist/evm/index.js +85 -68
- package/dist/evm/index.js.map +1 -1
- package/dist/evm/logs.d.ts.map +1 -1
- package/dist/evm/logs.js +47 -16
- package/dist/evm/logs.js.map +1 -1
- package/dist/evm/messages.d.ts +7 -6
- package/dist/evm/messages.d.ts.map +1 -1
- package/dist/evm/offchain.js +1 -1
- package/dist/evm/offchain.js.map +1 -1
- package/dist/evm/types.d.ts +10 -0
- package/dist/evm/types.d.ts.map +1 -0
- package/dist/evm/types.js +2 -0
- package/dist/evm/types.js.map +1 -0
- package/dist/execution.d.ts.map +1 -1
- package/dist/execution.js +9 -5
- package/dist/execution.js.map +1 -1
- package/dist/extra-args.d.ts.map +1 -1
- package/dist/extra-args.js +4 -3
- package/dist/extra-args.js.map +1 -1
- package/dist/gas.d.ts.map +1 -1
- package/dist/gas.js +3 -2
- package/dist/gas.js.map +1 -1
- package/dist/hasher/hasher.d.ts.map +1 -1
- package/dist/hasher/hasher.js +2 -1
- package/dist/hasher/hasher.js.map +1 -1
- package/dist/hasher/merklemulti.d.ts.map +1 -1
- package/dist/hasher/merklemulti.js +9 -8
- package/dist/hasher/merklemulti.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/offchain.d.ts.map +1 -1
- package/dist/offchain.js +5 -8
- package/dist/offchain.js.map +1 -1
- package/dist/requests.d.ts +1 -1
- package/dist/requests.d.ts.map +1 -1
- package/dist/requests.js +37 -43
- package/dist/requests.js.map +1 -1
- package/dist/selectors.d.ts.map +1 -1
- package/dist/selectors.js +22 -0
- package/dist/selectors.js.map +1 -1
- package/dist/solana/cleanup.d.ts +2 -2
- package/dist/solana/cleanup.d.ts.map +1 -1
- package/dist/solana/cleanup.js +2 -3
- package/dist/solana/cleanup.js.map +1 -1
- package/dist/solana/exec.d.ts.map +1 -1
- package/dist/solana/exec.js +12 -12
- package/dist/solana/exec.js.map +1 -1
- package/dist/solana/hasher.d.ts.map +1 -1
- package/dist/solana/hasher.js +6 -5
- package/dist/solana/hasher.js.map +1 -1
- package/dist/solana/index.d.ts +30 -13
- package/dist/solana/index.d.ts.map +1 -1
- package/dist/solana/index.js +96 -143
- package/dist/solana/index.js.map +1 -1
- package/dist/solana/logs.d.ts +15 -0
- package/dist/solana/logs.d.ts.map +1 -0
- package/dist/solana/logs.js +106 -0
- package/dist/solana/logs.js.map +1 -0
- package/dist/solana/offchain.d.ts.map +1 -1
- package/dist/solana/offchain.js +6 -5
- package/dist/solana/offchain.js.map +1 -1
- package/dist/solana/patchBorsh.d.ts.map +1 -1
- package/dist/solana/patchBorsh.js +3 -2
- package/dist/solana/patchBorsh.js.map +1 -1
- package/dist/solana/send.d.ts.map +1 -1
- package/dist/solana/send.js +8 -7
- package/dist/solana/send.js.map +1 -1
- package/dist/solana/utils.d.ts +7 -8
- package/dist/solana/utils.d.ts.map +1 -1
- package/dist/solana/utils.js +23 -11
- package/dist/solana/utils.js.map +1 -1
- package/dist/sui/discovery.d.ts +18 -0
- package/dist/sui/discovery.d.ts.map +1 -0
- package/dist/sui/discovery.js +116 -0
- package/dist/sui/discovery.js.map +1 -0
- package/dist/sui/events.d.ts +36 -0
- package/dist/sui/events.d.ts.map +1 -0
- package/dist/sui/events.js +179 -0
- package/dist/sui/events.js.map +1 -0
- package/dist/sui/hasher.d.ts.map +1 -1
- package/dist/sui/hasher.js +6 -5
- package/dist/sui/hasher.js.map +1 -1
- package/dist/sui/index.d.ts +69 -41
- package/dist/sui/index.d.ts.map +1 -1
- package/dist/sui/index.js +402 -65
- package/dist/sui/index.js.map +1 -1
- package/dist/sui/manuallyExec/encoder.d.ts +8 -0
- package/dist/sui/manuallyExec/encoder.d.ts.map +1 -0
- package/dist/sui/manuallyExec/encoder.js +76 -0
- package/dist/sui/manuallyExec/encoder.js.map +1 -0
- package/dist/sui/manuallyExec/index.d.ts +37 -0
- package/dist/sui/manuallyExec/index.d.ts.map +1 -0
- package/dist/sui/manuallyExec/index.js +81 -0
- package/dist/sui/manuallyExec/index.js.map +1 -0
- package/dist/sui/objects.d.ts +46 -0
- package/dist/sui/objects.d.ts.map +1 -0
- package/dist/sui/objects.js +259 -0
- package/dist/sui/objects.js.map +1 -0
- package/dist/ton/bindings/offramp.d.ts +48 -0
- package/dist/ton/bindings/offramp.d.ts.map +1 -0
- package/dist/ton/bindings/offramp.js +63 -0
- package/dist/ton/bindings/offramp.js.map +1 -0
- package/dist/ton/bindings/onramp.d.ts +40 -0
- package/dist/ton/bindings/onramp.d.ts.map +1 -0
- package/dist/ton/bindings/onramp.js +51 -0
- package/dist/ton/bindings/onramp.js.map +1 -0
- package/dist/ton/bindings/router.d.ts +47 -0
- package/dist/ton/bindings/router.d.ts.map +1 -0
- package/dist/ton/bindings/router.js +51 -0
- package/dist/ton/bindings/router.js.map +1 -0
- package/dist/ton/exec.d.ts +18 -0
- package/dist/ton/exec.d.ts.map +1 -0
- package/dist/ton/exec.js +28 -0
- package/dist/ton/exec.js.map +1 -0
- package/dist/ton/hasher.d.ts +27 -0
- package/dist/ton/hasher.d.ts.map +1 -0
- package/dist/ton/hasher.js +134 -0
- package/dist/ton/hasher.js.map +1 -0
- package/dist/ton/index.d.ts +247 -0
- package/dist/ton/index.d.ts.map +1 -0
- package/dist/ton/index.js +781 -0
- package/dist/ton/index.js.map +1 -0
- package/dist/ton/logs.d.ts +26 -0
- package/dist/ton/logs.d.ts.map +1 -0
- package/dist/ton/logs.js +126 -0
- package/dist/ton/logs.js.map +1 -0
- package/dist/ton/types.d.ts +37 -0
- package/dist/ton/types.d.ts.map +1 -0
- package/dist/ton/types.js +92 -0
- package/dist/ton/types.js.map +1 -0
- package/dist/ton/utils.d.ts +67 -0
- package/dist/ton/utils.d.ts.map +1 -0
- package/dist/ton/utils.js +425 -0
- package/dist/ton/utils.js.map +1 -0
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/utils.d.ts +10 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +52 -17
- package/dist/utils.js.map +1 -1
- package/package.json +12 -10
- package/src/aptos/hasher.ts +10 -6
- package/src/aptos/index.ts +50 -31
- package/src/aptos/logs.ts +85 -29
- package/src/aptos/token.ts +5 -1
- package/src/aptos/types.ts +6 -6
- package/src/chain.ts +83 -12
- package/src/commits.ts +23 -11
- package/src/errors/CCIPError.ts +86 -0
- package/src/errors/codes.ts +179 -0
- package/src/errors/index.ts +175 -0
- package/src/errors/recovery.ts +170 -0
- package/src/errors/specialized.ts +1655 -0
- package/src/errors/utils.ts +73 -0
- package/src/evm/abi/CommitStore_1_5.ts +1 -1
- package/src/evm/abi/LockReleaseTokenPool_1_5.ts +1 -1
- package/src/evm/abi/OffRamp_1_5.ts +1 -1
- package/src/evm/abi/OnRamp_1_5.ts +1 -1
- package/src/evm/abi/PriceRegistry_1_2.ts +438 -0
- package/src/evm/const.ts +2 -0
- package/src/evm/hasher.ts +7 -6
- package/src/evm/index.ts +104 -86
- package/src/evm/logs.ts +64 -16
- package/src/evm/messages.ts +14 -14
- package/src/evm/offchain.ts +1 -1
- package/src/evm/types.ts +11 -0
- package/src/execution.ts +13 -9
- package/src/extra-args.ts +4 -3
- package/src/gas.ts +10 -3
- package/src/hasher/hasher.ts +2 -1
- package/src/hasher/merklemulti.ts +18 -8
- package/src/index.ts +14 -2
- package/src/offchain.ts +10 -14
- package/src/requests.ts +51 -53
- package/src/selectors.ts +23 -0
- package/src/solana/cleanup.ts +2 -4
- package/src/solana/exec.ts +13 -13
- package/src/solana/hasher.ts +9 -5
- package/src/solana/index.ts +126 -200
- package/src/solana/logs.ts +155 -0
- package/src/solana/offchain.ts +10 -7
- package/src/solana/patchBorsh.ts +3 -2
- package/src/solana/send.ts +14 -7
- package/src/solana/utils.ts +31 -17
- package/src/sui/discovery.ts +163 -0
- package/src/sui/events.ts +328 -0
- package/src/sui/hasher.ts +6 -5
- package/src/sui/index.ts +528 -80
- package/src/sui/manuallyExec/encoder.ts +88 -0
- package/src/sui/manuallyExec/index.ts +137 -0
- package/src/sui/objects.ts +358 -0
- package/src/ton/bindings/offramp.ts +96 -0
- package/src/ton/bindings/onramp.ts +72 -0
- package/src/ton/bindings/router.ts +65 -0
- package/src/ton/exec.ts +44 -0
- package/src/ton/hasher.ts +184 -0
- package/src/ton/index.ts +989 -0
- package/src/ton/logs.ts +157 -0
- package/src/ton/types.ts +143 -0
- package/src/ton/utils.ts +514 -0
- package/src/types.ts +6 -2
- package/src/utils.ts +58 -23
- package/tsconfig.json +2 -1
package/src/solana/index.ts
CHANGED
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
SYSVAR_CLOCK_PUBKEY,
|
|
14
14
|
SystemProgram,
|
|
15
15
|
} from '@solana/web3.js'
|
|
16
|
-
import type BN from 'bn.js'
|
|
17
16
|
import bs58 from 'bs58'
|
|
18
17
|
import {
|
|
19
18
|
type BytesLike,
|
|
@@ -29,13 +28,31 @@ import {
|
|
|
29
28
|
import { type Memoized, memoize } from 'micro-memoize'
|
|
30
29
|
import type { PickDeep, SetRequired } from 'type-fest'
|
|
31
30
|
|
|
31
|
+
import { type LogFilter, type TokenInfo, type TokenPoolRemote, Chain } from '../chain.ts'
|
|
32
32
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
CCIPBlockTimeNotFoundError,
|
|
34
|
+
CCIPContractNotRouterError,
|
|
35
|
+
CCIPDataFormatUnsupportedError,
|
|
36
|
+
CCIPExecutionReportChainMismatchError,
|
|
37
|
+
CCIPExecutionStateInvalidError,
|
|
38
|
+
CCIPExtraArgsInvalidError,
|
|
39
|
+
CCIPExtraArgsLengthInvalidError,
|
|
40
|
+
CCIPLogDataMissingError,
|
|
41
|
+
CCIPLogsAddressRequiredError,
|
|
42
|
+
CCIPOnRampRequiredError,
|
|
43
|
+
CCIPSolanaExtraArgsEncodingError,
|
|
44
|
+
CCIPSolanaOffRampEventsNotFoundError,
|
|
45
|
+
CCIPSolanaRefAddressesNotFoundError,
|
|
46
|
+
CCIPSolanaTopicsInvalidError,
|
|
47
|
+
CCIPSplTokenInvalidError,
|
|
48
|
+
CCIPTokenDataParseError,
|
|
49
|
+
CCIPTokenNotConfiguredError,
|
|
50
|
+
CCIPTokenPoolChainConfigNotFoundError,
|
|
51
|
+
CCIPTokenPoolInfoNotFoundError,
|
|
52
|
+
CCIPTokenPoolStateNotFoundError,
|
|
53
|
+
CCIPTransactionNotFoundError,
|
|
54
|
+
CCIPWalletInvalidError,
|
|
55
|
+
} from '../errors/index.ts'
|
|
39
56
|
import { type EVMExtraArgsV2, type ExtraArgs, EVMExtraArgsV2Tag } from '../extra-args.ts'
|
|
40
57
|
import type { LeafHasher } from '../hasher/common.ts'
|
|
41
58
|
import SELECTORS from '../selectors.ts'
|
|
@@ -61,6 +78,7 @@ import {
|
|
|
61
78
|
ExecutionState,
|
|
62
79
|
} from '../types.ts'
|
|
63
80
|
import {
|
|
81
|
+
bytesToBuffer,
|
|
64
82
|
createRateLimitedFetch,
|
|
65
83
|
decodeAddress,
|
|
66
84
|
decodeOnRampAddress,
|
|
@@ -79,11 +97,12 @@ import { IDL as BURN_MINT_TOKEN_POOL } from './idl/1.6.0/BURN_MINT_TOKEN_POOL.ts
|
|
|
79
97
|
import { IDL as CCIP_CCTP_TOKEN_POOL } from './idl/1.6.0/CCIP_CCTP_TOKEN_POOL.ts'
|
|
80
98
|
import { IDL as CCIP_OFFRAMP_IDL } from './idl/1.6.0/CCIP_OFFRAMP.ts'
|
|
81
99
|
import { IDL as CCIP_ROUTER_IDL } from './idl/1.6.0/CCIP_ROUTER.ts'
|
|
100
|
+
import { getTransactionsForAddress } from './logs.ts'
|
|
82
101
|
import { fetchSolanaOffchainTokenData } from './offchain.ts'
|
|
83
102
|
import { generateUnsignedCcipSend, getFee } from './send.ts'
|
|
84
103
|
import { type CCIPMessage_V1_6_Solana, type UnsignedSolanaTx, isWallet } from './types.ts'
|
|
85
104
|
import {
|
|
86
|
-
|
|
105
|
+
convertRateLimiter,
|
|
87
106
|
getErrorFromLogs,
|
|
88
107
|
hexDiscriminator,
|
|
89
108
|
parseSolanaLogs,
|
|
@@ -99,18 +118,20 @@ import { patchBorsh } from './patchBorsh.ts'
|
|
|
99
118
|
|
|
100
119
|
const routerCoder = new BorshCoder(CCIP_ROUTER_IDL)
|
|
101
120
|
const offrampCoder = new BorshCoder(CCIP_OFFRAMP_IDL)
|
|
102
|
-
const
|
|
121
|
+
const TOKEN_POOL_IDL = {
|
|
103
122
|
...BURN_MINT_TOKEN_POOL,
|
|
104
123
|
types: BASE_TOKEN_POOL.types,
|
|
105
124
|
events: BASE_TOKEN_POOL.events,
|
|
106
125
|
errors: [...BASE_TOKEN_POOL.errors, ...BURN_MINT_TOKEN_POOL.errors],
|
|
107
|
-
}
|
|
108
|
-
const
|
|
126
|
+
}
|
|
127
|
+
const tokenPoolCoder = new BorshCoder(TOKEN_POOL_IDL)
|
|
128
|
+
const CCTP_TOKEN_POOL_IDL = {
|
|
109
129
|
...CCIP_CCTP_TOKEN_POOL,
|
|
110
130
|
types: [...BASE_TOKEN_POOL.types, ...CCIP_CCTP_TOKEN_POOL.types],
|
|
111
131
|
events: [...BASE_TOKEN_POOL.events, ...CCIP_CCTP_TOKEN_POOL.events],
|
|
112
132
|
errors: [...BASE_TOKEN_POOL.errors, ...CCIP_CCTP_TOKEN_POOL.errors],
|
|
113
|
-
}
|
|
133
|
+
}
|
|
134
|
+
const cctpTokenPoolCoder = new BorshCoder(CCTP_TOKEN_POOL_IDL)
|
|
114
135
|
// const commonCoder = new BorshCoder(CCIP_COMMON_IDL)
|
|
115
136
|
|
|
116
137
|
interface ParsedTokenInfo {
|
|
@@ -148,6 +169,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
148
169
|
|
|
149
170
|
connection: Connection
|
|
150
171
|
commitment: Commitment = 'confirmed'
|
|
172
|
+
readonly destroy$: Promise<void>
|
|
151
173
|
|
|
152
174
|
/**
|
|
153
175
|
* Creates a new SolanaChain instance.
|
|
@@ -158,6 +180,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
158
180
|
super(network, ctx)
|
|
159
181
|
|
|
160
182
|
this.connection = connection
|
|
183
|
+
this.destroy$ = new Promise<void>((resolve) => (this.destroy = resolve))
|
|
161
184
|
|
|
162
185
|
// Memoize expensive operations
|
|
163
186
|
this.typeAndVersion = memoize(this.typeAndVersion.bind(this), {
|
|
@@ -167,7 +190,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
167
190
|
this.getBlockTimestamp = memoize(this.getBlockTimestamp.bind(this), {
|
|
168
191
|
async: true,
|
|
169
192
|
maxSize: 100,
|
|
170
|
-
forceUpdate: (
|
|
193
|
+
forceUpdate: ([k]) => typeof k !== 'number' || k <= 0,
|
|
171
194
|
})
|
|
172
195
|
this.getTransaction = memoize(this.getTransaction.bind(this), {
|
|
173
196
|
maxSize: 100,
|
|
@@ -220,7 +243,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
220
243
|
static _getConnection(url: string, ctx?: WithLogger): Connection {
|
|
221
244
|
const { logger = console } = ctx ?? {}
|
|
222
245
|
if (!url.startsWith('http') && !url.startsWith('ws')) {
|
|
223
|
-
throw new
|
|
246
|
+
throw new CCIPDataFormatUnsupportedError(
|
|
224
247
|
`Invalid Solana RPC URL format (should be https://, http://, wss://, or ws://): ${url}`,
|
|
225
248
|
)
|
|
226
249
|
}
|
|
@@ -258,19 +281,21 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
258
281
|
|
|
259
282
|
// cached
|
|
260
283
|
/** {@inheritDoc Chain.getBlockTimestamp} */
|
|
261
|
-
async getBlockTimestamp(block: number | 'finalized'): Promise<number> {
|
|
262
|
-
if (block
|
|
263
|
-
const slot = await this.connection.getSlot('
|
|
284
|
+
async getBlockTimestamp(block: number | 'latest' | 'finalized'): Promise<number> {
|
|
285
|
+
if (typeof block !== 'number') {
|
|
286
|
+
const slot = await this.connection.getSlot(block === 'latest' ? 'confirmed' : block)
|
|
264
287
|
const blockTime = await this.connection.getBlockTime(slot)
|
|
265
288
|
if (blockTime === null) {
|
|
266
|
-
throw new
|
|
289
|
+
throw new CCIPBlockTimeNotFoundError(`finalized slot ${slot}`)
|
|
267
290
|
}
|
|
268
291
|
return blockTime
|
|
292
|
+
} else if (block <= 0) {
|
|
293
|
+
block = (await this.connection.getSlot('confirmed')) + block
|
|
269
294
|
}
|
|
270
295
|
|
|
271
296
|
const blockTime = await this.connection.getBlockTime(block)
|
|
272
297
|
if (blockTime === null) {
|
|
273
|
-
throw new
|
|
298
|
+
throw new CCIPBlockTimeNotFoundError(block)
|
|
274
299
|
}
|
|
275
300
|
return blockTime
|
|
276
301
|
}
|
|
@@ -281,7 +306,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
281
306
|
commitment: 'confirmed',
|
|
282
307
|
maxSupportedTransactionVersion: 0,
|
|
283
308
|
})
|
|
284
|
-
if (!tx) throw new
|
|
309
|
+
if (!tx) throw new CCIPTransactionNotFoundError(hash)
|
|
285
310
|
if (tx.blockTime) {
|
|
286
311
|
;(
|
|
287
312
|
this.getBlockTimestamp as Memoized<typeof this.getBlockTimestamp, { async: true }>
|
|
@@ -321,69 +346,9 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
321
346
|
async *getTransactionsForAddress(
|
|
322
347
|
opts: Omit<LogFilter, 'topics'>,
|
|
323
348
|
): AsyncGenerator<SolanaTransaction> {
|
|
324
|
-
if (
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const limit = Math.min(opts?.page || 1000, 1000)
|
|
328
|
-
if (opts.startBlock || opts.startTime) {
|
|
329
|
-
// forward collect all matching sigs in array
|
|
330
|
-
allSignatures = [] as Awaited<ReturnType<typeof this.connection.getSignaturesForAddress>>
|
|
331
|
-
let batch: typeof allSignatures
|
|
332
|
-
do {
|
|
333
|
-
batch = await this.connection.getSignaturesForAddress(
|
|
334
|
-
new PublicKey(opts.address),
|
|
335
|
-
{ limit, before: allSignatures[allSignatures.length - 1]?.signature },
|
|
336
|
-
'confirmed',
|
|
337
|
-
)
|
|
338
|
-
|
|
339
|
-
while (
|
|
340
|
-
batch.length > 0 &&
|
|
341
|
-
(batch[batch.length - 1].slot < (opts.startBlock || 0) ||
|
|
342
|
-
(batch[batch.length - 1].blockTime || -1) < (opts.startTime || 0))
|
|
343
|
-
) {
|
|
344
|
-
batch.length-- // truncate tail of txs which are older than requested start
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
allSignatures.push(...batch) // concat in descending order
|
|
348
|
-
} while (batch.length >= limit)
|
|
349
|
-
|
|
350
|
-
allSignatures.reverse()
|
|
351
|
-
|
|
352
|
-
while (
|
|
353
|
-
opts.endBlock &&
|
|
354
|
-
allSignatures.length > 0 &&
|
|
355
|
-
allSignatures[allSignatures.length - 1].slot > opts.endBlock
|
|
356
|
-
) {
|
|
357
|
-
allSignatures.length-- // truncate head (after reverse) of txs newer than requested end
|
|
358
|
-
}
|
|
359
|
-
} else {
|
|
360
|
-
allSignatures = async function* (this: SolanaChain) {
|
|
361
|
-
let batch: Awaited<ReturnType<typeof this.connection.getSignaturesForAddress>> | undefined
|
|
362
|
-
do {
|
|
363
|
-
batch = await this.connection.getSignaturesForAddress(
|
|
364
|
-
new PublicKey(opts.address!),
|
|
365
|
-
{
|
|
366
|
-
limit,
|
|
367
|
-
before: batch?.length
|
|
368
|
-
? batch[batch.length - 1].signature
|
|
369
|
-
: opts.endBefore
|
|
370
|
-
? opts.endBefore
|
|
371
|
-
: undefined,
|
|
372
|
-
},
|
|
373
|
-
'confirmed',
|
|
374
|
-
)
|
|
375
|
-
for (const sig of batch) {
|
|
376
|
-
if (opts.endBlock && sig.slot > opts.endBlock) continue
|
|
377
|
-
yield sig
|
|
378
|
-
}
|
|
379
|
-
} while (batch.length >= limit)
|
|
380
|
-
}.call(this) // generate backwards until depleting getSignaturesForAddress
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Process signatures
|
|
384
|
-
for await (const signatureInfo of allSignatures) {
|
|
385
|
-
yield await this.getTransaction(signatureInfo.signature)
|
|
386
|
-
}
|
|
349
|
+
if (opts.watch instanceof Promise)
|
|
350
|
+
opts = { ...opts, watch: Promise.race([opts.watch, this.destroy$]) }
|
|
351
|
+
yield* getTransactionsForAddress(opts, this)
|
|
387
352
|
}
|
|
388
353
|
|
|
389
354
|
/**
|
|
@@ -404,45 +369,46 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
404
369
|
* - `startBlock`: Starting slot number (inclusive)
|
|
405
370
|
* - `startTime`: Starting Unix timestamp (inclusive)
|
|
406
371
|
* - `endBlock`: Ending slot number (inclusive)
|
|
372
|
+
* - `endBefore`: Fetch signatures before this transaction
|
|
407
373
|
* - `address`: Program address to filter logs by (required for Solana)
|
|
408
374
|
* - `topics`: Array of topics to filter logs by (optional); either 0x-8B discriminants or event names
|
|
375
|
+
* - `watch`: Watch for new logs
|
|
409
376
|
* - `programs`: Special option to allow querying by address of interest, but yielding matching
|
|
410
377
|
* logs from specific (string address) program or any (true)
|
|
411
|
-
* - `commit`: Special param for fetching ExecutionReceipts, to narrow down the search
|
|
412
378
|
* @returns AsyncIterableIterator of parsed Log_ objects.
|
|
413
379
|
*/
|
|
414
380
|
async *getLogs(
|
|
415
|
-
opts: LogFilter & {
|
|
381
|
+
opts: LogFilter & { programs?: string[] | true },
|
|
416
382
|
): AsyncGenerator<Log_ & { tx: SolanaTransaction }> {
|
|
417
383
|
let programs: true | string[]
|
|
418
|
-
if (
|
|
419
|
-
|
|
420
|
-
opts.address = opts.sender
|
|
421
|
-
programs = true
|
|
422
|
-
} else if (!opts.address) {
|
|
423
|
-
throw new Error('Program address is required for Solana log filtering')
|
|
384
|
+
if (!opts.address) {
|
|
385
|
+
throw new CCIPLogsAddressRequiredError()
|
|
424
386
|
} else if (!opts.programs) {
|
|
425
387
|
programs = [opts.address]
|
|
426
388
|
} else {
|
|
427
389
|
programs = opts.programs
|
|
428
390
|
}
|
|
391
|
+
let topics
|
|
429
392
|
if (opts.topics?.length) {
|
|
430
393
|
if (!opts.topics.every((topic) => typeof topic === 'string'))
|
|
431
|
-
throw new
|
|
394
|
+
throw new CCIPSolanaTopicsInvalidError()
|
|
432
395
|
// append events discriminants (if not 0x-8B already), but keep OG topics
|
|
433
|
-
|
|
396
|
+
topics = [
|
|
397
|
+
...opts.topics,
|
|
434
398
|
...opts.topics.filter((t) => !isHexString(t, 8)).map((t) => hexDiscriminator(t)),
|
|
435
|
-
|
|
399
|
+
]
|
|
436
400
|
}
|
|
437
401
|
|
|
438
402
|
// Process signatures and yield logs
|
|
439
403
|
for await (const tx of this.getTransactionsForAddress(opts)) {
|
|
440
|
-
|
|
404
|
+
let logs = tx.logs
|
|
405
|
+
if (opts.startBlock == null && opts.startTime == null) logs = logs.toReversed() // backwards
|
|
406
|
+
for (const log of logs) {
|
|
441
407
|
// Filter and yield logs from the specified program, and which match event discriminant or log prefix
|
|
442
408
|
if (
|
|
443
409
|
(programs !== true && !programs.includes(log.address)) ||
|
|
444
|
-
(
|
|
445
|
-
!
|
|
410
|
+
(topics &&
|
|
411
|
+
!topics.some(
|
|
446
412
|
(t) =>
|
|
447
413
|
t === log.topics[0] || (typeof log.data === 'string' && log.data.startsWith(t)),
|
|
448
414
|
))
|
|
@@ -464,7 +430,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
464
430
|
onRamp?: string,
|
|
465
431
|
opts?: { page?: number },
|
|
466
432
|
): Promise<CCIPRequest> {
|
|
467
|
-
if (!onRamp) throw new
|
|
433
|
+
if (!onRamp) throw new CCIPOnRampRequiredError()
|
|
468
434
|
return fetchCCIPRequestById(this, messageId, { address: onRamp, ...opts })
|
|
469
435
|
}
|
|
470
436
|
|
|
@@ -472,7 +438,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
472
438
|
async fetchAllMessagesInBatch<
|
|
473
439
|
R extends PickDeep<
|
|
474
440
|
CCIPRequest,
|
|
475
|
-
'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.
|
|
441
|
+
'lane' | `log.${'topics' | 'address' | 'blockNumber'}` | 'message.sequenceNumber'
|
|
476
442
|
>,
|
|
477
443
|
>(
|
|
478
444
|
request: R,
|
|
@@ -528,8 +494,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
528
494
|
offRamp_,
|
|
529
495
|
)
|
|
530
496
|
const referenceAddressesPda = await this.connection.getAccountInfo(referenceAddressesAddr)
|
|
531
|
-
if (!referenceAddressesPda)
|
|
532
|
-
throw new Error(`referenceAddresses account not found for offRamp=${offRamp}`)
|
|
497
|
+
if (!referenceAddressesPda) throw new CCIPSolanaRefAddressesNotFoundError(offRamp)
|
|
533
498
|
|
|
534
499
|
// Decode the config account using the program's coder
|
|
535
500
|
const { router }: { router: PublicKey } = program.coder.accounts.decode(
|
|
@@ -562,7 +527,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
562
527
|
})) {
|
|
563
528
|
return [log.address] // assume single offramp per router/deployment on Solana
|
|
564
529
|
}
|
|
565
|
-
throw new
|
|
530
|
+
throw new CCIPSolanaOffRampEventsNotFoundError(feeQuoter.toString())
|
|
566
531
|
}
|
|
567
532
|
|
|
568
533
|
/** {@inheritDoc Chain.getOnRampForRouter} */
|
|
@@ -599,7 +564,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
599
564
|
/** {@inheritDoc Chain.getTokenForTokenPool} */
|
|
600
565
|
async getTokenForTokenPool(tokenPool: string): Promise<string> {
|
|
601
566
|
const tokenPoolInfo = await this.connection.getAccountInfo(new PublicKey(tokenPool))
|
|
602
|
-
if (!tokenPoolInfo) throw new
|
|
567
|
+
if (!tokenPoolInfo) throw new CCIPTokenPoolInfoNotFoundError(tokenPool)
|
|
603
568
|
const { config }: { config: { mint: PublicKey } } = tokenPoolCoder.accounts.decode(
|
|
604
569
|
'state',
|
|
605
570
|
tokenPoolInfo.data,
|
|
@@ -620,7 +585,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
620
585
|
mintInfo.value.data.program !== 'spl-token' &&
|
|
621
586
|
mintInfo.value.data.program !== 'spl-token-2022')
|
|
622
587
|
) {
|
|
623
|
-
throw new
|
|
588
|
+
throw new CCIPSplTokenInvalidError(token)
|
|
624
589
|
}
|
|
625
590
|
|
|
626
591
|
if (typeof mintInfo.value.data === 'object' && 'parsed' in mintInfo.value.data) {
|
|
@@ -653,7 +618,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
653
618
|
decimals: data.decimals,
|
|
654
619
|
}
|
|
655
620
|
} else {
|
|
656
|
-
throw new
|
|
621
|
+
throw new CCIPTokenDataParseError(token)
|
|
657
622
|
}
|
|
658
623
|
}
|
|
659
624
|
|
|
@@ -747,14 +712,13 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
747
712
|
const message = decoded.data.message
|
|
748
713
|
|
|
749
714
|
// Convert BN/number types to bigints
|
|
715
|
+
const messageId = hexlify(new Uint8Array(message.header.messageId))
|
|
750
716
|
const sourceChainSelector = BigInt(message.header.sourceChainSelector.toString())
|
|
751
717
|
const destChainSelector = BigInt(message.header.destChainSelector.toString())
|
|
752
718
|
const sequenceNumber = BigInt(message.header.sequenceNumber.toString())
|
|
753
719
|
const nonce = BigInt(message.header.nonce.toString())
|
|
754
720
|
const destNetwork = networkInfo(destChainSelector)
|
|
755
721
|
|
|
756
|
-
// Convert message fields to expected format
|
|
757
|
-
const messageId = hexlify(new Uint8Array(message.header.messageId))
|
|
758
722
|
const sender = message.sender.toString()
|
|
759
723
|
const data_ = getDataBytes(message.data)
|
|
760
724
|
// TODO: extract this into a proper normalize/decode/reencode data utility
|
|
@@ -780,17 +744,16 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
780
744
|
// Parse gas limit from extraArgs
|
|
781
745
|
const extraArgs = hexlify(message.extraArgs)
|
|
782
746
|
const parsed = this.decodeExtraArgs(extraArgs)
|
|
783
|
-
if (!parsed) throw new
|
|
747
|
+
if (!parsed) throw new CCIPExtraArgsInvalidError('SVM', extraArgs)
|
|
784
748
|
const { _tag, ...rest } = parsed
|
|
785
749
|
|
|
786
750
|
return {
|
|
787
|
-
header
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
},
|
|
751
|
+
// merge header fields to message
|
|
752
|
+
messageId,
|
|
753
|
+
sourceChainSelector,
|
|
754
|
+
destChainSelector: destChainSelector,
|
|
755
|
+
sequenceNumber: sequenceNumber,
|
|
756
|
+
nonce,
|
|
794
757
|
sender,
|
|
795
758
|
receiver,
|
|
796
759
|
data: msgData,
|
|
@@ -823,7 +786,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
823
786
|
allowOutOfOrderExecution: data[4 + 16] == 1,
|
|
824
787
|
}
|
|
825
788
|
}
|
|
826
|
-
throw new
|
|
789
|
+
throw new CCIPExtraArgsLengthInvalidError(dataLength(data))
|
|
827
790
|
}
|
|
828
791
|
default:
|
|
829
792
|
return
|
|
@@ -836,7 +799,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
836
799
|
* @returns Encoded extra arguments as hex string.
|
|
837
800
|
*/
|
|
838
801
|
static encodeExtraArgs(args: ExtraArgs): string {
|
|
839
|
-
if ('computeUnits' in args) throw new
|
|
802
|
+
if ('computeUnits' in args) throw new CCIPSolanaExtraArgsEncodingError()
|
|
840
803
|
const gasLimitUint128Le = toLeArray(args.gasLimit, 16)
|
|
841
804
|
return concat([
|
|
842
805
|
EVMExtraArgsV2Tag,
|
|
@@ -857,7 +820,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
857
820
|
): CommitReport[] | undefined {
|
|
858
821
|
// Check if this is a CommitReportAccepted event by looking at the discriminant
|
|
859
822
|
if (!log.data || typeof log.data !== 'string') {
|
|
860
|
-
throw new
|
|
823
|
+
throw new CCIPLogDataMissingError()
|
|
861
824
|
}
|
|
862
825
|
|
|
863
826
|
try {
|
|
@@ -908,7 +871,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
908
871
|
static decodeReceipt(log: Pick<Log_, 'data' | 'tx' | 'index'>): ExecutionReceipt | undefined {
|
|
909
872
|
// Check if this is a ExecutionStateChanged event by looking at the discriminant
|
|
910
873
|
if (!log.data || typeof log.data !== 'string') {
|
|
911
|
-
throw new
|
|
874
|
+
throw new CCIPLogDataMissingError()
|
|
912
875
|
}
|
|
913
876
|
|
|
914
877
|
try {
|
|
@@ -935,7 +898,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
935
898
|
state = ExecutionState.Success
|
|
936
899
|
} else if (decoded.data.state.failure) {
|
|
937
900
|
state = ExecutionState.Failed
|
|
938
|
-
} else throw new
|
|
901
|
+
} else throw new CCIPExecutionStateInvalidError(util.inspect(decoded.data.state))
|
|
939
902
|
|
|
940
903
|
let returnData
|
|
941
904
|
if (log.tx) {
|
|
@@ -980,6 +943,19 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
980
943
|
return encodeBase58(getDataBytes(bytes))
|
|
981
944
|
}
|
|
982
945
|
|
|
946
|
+
/**
|
|
947
|
+
* Validates a transaction hash format for Solana
|
|
948
|
+
*/
|
|
949
|
+
static isTxHash(v: unknown): v is string {
|
|
950
|
+
if (typeof v !== 'string') return false
|
|
951
|
+
try {
|
|
952
|
+
return bs58.decode(v).length === 64
|
|
953
|
+
} catch (_) {
|
|
954
|
+
// pass
|
|
955
|
+
}
|
|
956
|
+
return false
|
|
957
|
+
}
|
|
958
|
+
|
|
983
959
|
/**
|
|
984
960
|
* Gets the leaf hasher for Solana destination chains.
|
|
985
961
|
* @param lane - Lane configuration.
|
|
@@ -992,7 +968,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
992
968
|
/** {@inheritDoc Chain.getTokenAdminRegistryFor} */
|
|
993
969
|
async getTokenAdminRegistryFor(address: string): Promise<string> {
|
|
994
970
|
const [type] = await this.typeAndVersion(address)
|
|
995
|
-
if (!type.includes('Router')) throw new
|
|
971
|
+
if (!type.includes('Router')) throw new CCIPContractNotRouterError(address, type)
|
|
996
972
|
// Solana implements TokenAdminRegistry in the Router/OnRamp program
|
|
997
973
|
return address
|
|
998
974
|
}
|
|
@@ -1040,7 +1016,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1040
1016
|
opts: { wallet: unknown; approveMax?: boolean },
|
|
1041
1017
|
): Promise<CCIPRequest> {
|
|
1042
1018
|
const wallet = opts.wallet
|
|
1043
|
-
if (!isWallet(wallet)) throw new
|
|
1019
|
+
if (!isWallet(wallet)) throw new CCIPWalletInvalidError(util.inspect(wallet))
|
|
1044
1020
|
const unsigned = await this.generateUnsignedSendMessage(
|
|
1045
1021
|
wallet.publicKey.toBase58(),
|
|
1046
1022
|
router,
|
|
@@ -1079,7 +1055,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1079
1055
|
opts?: { forceBuffer?: boolean; forceLookupTable?: boolean },
|
|
1080
1056
|
): Promise<UnsignedSolanaTx> {
|
|
1081
1057
|
if (!('computeUnits' in execReport_.message))
|
|
1082
|
-
throw new
|
|
1058
|
+
throw new CCIPExecutionReportChainMismatchError('Solana')
|
|
1083
1059
|
const execReport = execReport_ as ExecutionReport<CCIPMessage_V1_6_Solana>
|
|
1084
1060
|
const offRamp_ = new PublicKey(offRamp)
|
|
1085
1061
|
return generateUnsignedExecuteReport(this, new PublicKey(payer), offRamp_, execReport, opts)
|
|
@@ -1098,7 +1074,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1098
1074
|
},
|
|
1099
1075
|
): Promise<ChainTransaction> {
|
|
1100
1076
|
const wallet = opts.wallet
|
|
1101
|
-
if (!isWallet(wallet)) throw new
|
|
1077
|
+
if (!isWallet(wallet)) throw new CCIPWalletInvalidError(util.inspect(wallet))
|
|
1102
1078
|
|
|
1103
1079
|
let hash
|
|
1104
1080
|
do {
|
|
@@ -1143,8 +1119,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1143
1119
|
*/
|
|
1144
1120
|
async cleanUpBuffers(opts: { wallet: unknown; waitDeactivation?: boolean }): Promise<void> {
|
|
1145
1121
|
const wallet = opts.wallet
|
|
1146
|
-
if (!isWallet(wallet)) throw new
|
|
1147
|
-
await cleanUpBuffers(this, wallet,
|
|
1122
|
+
if (!isWallet(wallet)) throw new CCIPWalletInvalidError(util.inspect(wallet))
|
|
1123
|
+
await cleanUpBuffers(this, wallet, opts)
|
|
1148
1124
|
}
|
|
1149
1125
|
|
|
1150
1126
|
/**
|
|
@@ -1181,8 +1157,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1181
1157
|
*/
|
|
1182
1158
|
override async fetchCommitReport(
|
|
1183
1159
|
commitStore: string,
|
|
1184
|
-
request: PickDeep<CCIPRequest, 'lane' | 'message.
|
|
1185
|
-
hints?: { startBlock?: number
|
|
1160
|
+
request: PickDeep<CCIPRequest, 'lane' | 'message.sequenceNumber' | 'tx.timestamp'>,
|
|
1161
|
+
hints?: Pick<LogFilter, 'page' | 'watch'> & { startBlock?: number },
|
|
1186
1162
|
): Promise<CCIPCommit> {
|
|
1187
1163
|
const commitsAroundSeqNum = await this.connection.getProgramAccounts(
|
|
1188
1164
|
new PublicKey(commitStore),
|
|
@@ -1205,7 +1181,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1205
1181
|
{
|
|
1206
1182
|
memcmp: {
|
|
1207
1183
|
offset: 8 + 1 + 8 + 32 + 8 + 1,
|
|
1208
|
-
bytes: encodeBase58(toLeArray(request.message.
|
|
1184
|
+
bytes: encodeBase58(toLeArray(request.message.sequenceNumber, 8).slice(1)),
|
|
1209
1185
|
},
|
|
1210
1186
|
},
|
|
1211
1187
|
],
|
|
@@ -1215,10 +1191,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1215
1191
|
// const merkleRoot = acc.account.data.subarray(8 + 1 + 8, 8 + 1 + 8 + 32)
|
|
1216
1192
|
const minSeqNr = acc.account.data.readBigUInt64LE(8 + 1 + 8 + 32 + 8)
|
|
1217
1193
|
const maxSeqNr = acc.account.data.readBigUInt64LE(8 + 1 + 8 + 32 + 8 + 8)
|
|
1218
|
-
if (
|
|
1219
|
-
minSeqNr > request.message.header.sequenceNumber ||
|
|
1220
|
-
maxSeqNr < request.message.header.sequenceNumber
|
|
1221
|
-
)
|
|
1194
|
+
if (minSeqNr > request.message.sequenceNumber || maxSeqNr < request.message.sequenceNumber)
|
|
1222
1195
|
continue
|
|
1223
1196
|
// we have all the commit report info, but we also need log details (txHash, etc)
|
|
1224
1197
|
for await (const log of this.getLogs({
|
|
@@ -1242,9 +1215,9 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1242
1215
|
/** {@inheritDoc Chain.fetchExecutionReceipts} */
|
|
1243
1216
|
override async *fetchExecutionReceipts(
|
|
1244
1217
|
offRamp: string,
|
|
1245
|
-
request: PickDeep<CCIPRequest, 'lane' | 'message.
|
|
1218
|
+
request: PickDeep<CCIPRequest, 'lane' | 'message.messageId' | 'tx.timestamp'>,
|
|
1246
1219
|
commit?: CCIPCommit,
|
|
1247
|
-
opts?:
|
|
1220
|
+
opts?: Pick<LogFilter, 'page' | 'watch'>,
|
|
1248
1221
|
): AsyncIterableIterator<CCIPExecution> {
|
|
1249
1222
|
let opts_: Parameters<SolanaChain['getLogs']>[0] | undefined = opts
|
|
1250
1223
|
if (commit) {
|
|
@@ -1284,8 +1257,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1284
1257
|
)
|
|
1285
1258
|
|
|
1286
1259
|
const tokenAdminRegistry = await this.connection.getAccountInfo(tokenAdminRegistryAddr)
|
|
1287
|
-
if (!tokenAdminRegistry)
|
|
1288
|
-
throw new Error(`Token ${token} is not configured in registry ${registry}`)
|
|
1260
|
+
if (!tokenAdminRegistry) throw new CCIPTokenNotConfiguredError(token, registry)
|
|
1289
1261
|
|
|
1290
1262
|
const config: {
|
|
1291
1263
|
administrator: string
|
|
@@ -1331,10 +1303,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1331
1303
|
}> {
|
|
1332
1304
|
// `tokenPool` is actually a State PDA in the tokenPoolProgram
|
|
1333
1305
|
const tokenPoolState = await this.connection.getAccountInfo(new PublicKey(tokenPool))
|
|
1334
|
-
if (!tokenPoolState
|
|
1335
|
-
|
|
1336
|
-
const { config }: { config: { mint: PublicKey; router: PublicKey } } =
|
|
1337
|
-
tokenPoolCoder.accounts.decode('state', tokenPoolState.data)
|
|
1306
|
+
if (!tokenPoolState || tokenPoolState.data.length < 266 + 32)
|
|
1307
|
+
throw new CCIPTokenPoolStateNotFoundError(tokenPool)
|
|
1338
1308
|
const tokenPoolProgram = tokenPoolState.owner.toBase58()
|
|
1339
1309
|
|
|
1340
1310
|
let typeAndVersion
|
|
@@ -1344,9 +1314,14 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1344
1314
|
// TokenPool may not have a typeAndVersion
|
|
1345
1315
|
}
|
|
1346
1316
|
|
|
1317
|
+
// const { config }: { config: IdlTypes<typeof BASE_TOKEN_POOL>['BaseConfig'] } =
|
|
1318
|
+
// tokenPoolCoder.accounts.decode('state', tokenPoolState.data)
|
|
1319
|
+
const mint = new PublicKey(tokenPoolState.data.subarray(41, 41 + 32))
|
|
1320
|
+
const router = new PublicKey(tokenPoolState.data.subarray(266, 266 + 32))
|
|
1321
|
+
|
|
1347
1322
|
return {
|
|
1348
|
-
token:
|
|
1349
|
-
router:
|
|
1323
|
+
token: mint.toBase58(),
|
|
1324
|
+
router: router.toBase58(),
|
|
1350
1325
|
tokenPoolProgram,
|
|
1351
1326
|
typeAndVersion,
|
|
1352
1327
|
}
|
|
@@ -1359,7 +1334,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1359
1334
|
): Promise<Record<string, TokenPoolRemote>> {
|
|
1360
1335
|
// `tokenPool` is actually a State PDA in the tokenPoolProgram
|
|
1361
1336
|
const tokenPoolState = await this.connection.getAccountInfo(new PublicKey(tokenPool))
|
|
1362
|
-
if (!tokenPoolState) throw new
|
|
1337
|
+
if (!tokenPoolState) throw new CCIPTokenPoolStateNotFoundError(tokenPool)
|
|
1363
1338
|
|
|
1364
1339
|
const tokenPoolProgram = tokenPoolState.owner
|
|
1365
1340
|
|
|
@@ -1385,8 +1360,10 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1385
1360
|
)
|
|
1386
1361
|
const chainConfigAcc = await this.connection.getAccountInfo(chainConfigAddr)
|
|
1387
1362
|
if (!chainConfigAcc)
|
|
1388
|
-
throw new
|
|
1389
|
-
|
|
1363
|
+
throw new CCIPTokenPoolChainConfigNotFoundError(
|
|
1364
|
+
chainConfigAddr.toBase58(),
|
|
1365
|
+
tokenPool,
|
|
1366
|
+
networkInfo(remoteChainSelector).name,
|
|
1390
1367
|
)
|
|
1391
1368
|
accounts = [
|
|
1392
1369
|
{
|
|
@@ -1408,31 +1385,7 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1408
1385
|
|
|
1409
1386
|
for (const acc of accounts) {
|
|
1410
1387
|
try {
|
|
1411
|
-
let base:
|
|
1412
|
-
remote: {
|
|
1413
|
-
poolAddresses: { address: Buffer }[]
|
|
1414
|
-
tokenAddress: { address: Buffer }
|
|
1415
|
-
decimals: number
|
|
1416
|
-
}
|
|
1417
|
-
inboundRateLimit: {
|
|
1418
|
-
tokens: BN
|
|
1419
|
-
lastUpdated: BN
|
|
1420
|
-
cfg: {
|
|
1421
|
-
enabled: boolean
|
|
1422
|
-
capacity: BN
|
|
1423
|
-
rate: BN
|
|
1424
|
-
}
|
|
1425
|
-
}
|
|
1426
|
-
outboundRateLimit: {
|
|
1427
|
-
tokens: BN
|
|
1428
|
-
lastUpdated: BN
|
|
1429
|
-
cfg: {
|
|
1430
|
-
enabled: boolean
|
|
1431
|
-
capacity: BN
|
|
1432
|
-
rate: BN
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
}
|
|
1388
|
+
let base: IdlTypes<typeof BASE_TOKEN_POOL>['BaseChain']
|
|
1436
1389
|
try {
|
|
1437
1390
|
;({ base } = tokenPoolCoder.accounts.decode('chainConfig', acc.account.data))
|
|
1438
1391
|
} catch (_) {
|
|
@@ -1465,35 +1418,8 @@ export class SolanaChain extends Chain<typeof ChainFamily.Solana> {
|
|
|
1465
1418
|
decodeAddress(pool.address, remoteNetwork.family),
|
|
1466
1419
|
)
|
|
1467
1420
|
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
inboundRateLimiterState = {
|
|
1471
|
-
tokens: BigInt(base.inboundRateLimit.tokens.toString()),
|
|
1472
|
-
capacity: BigInt(base.inboundRateLimit.cfg.capacity.toString()),
|
|
1473
|
-
rate: BigInt(base.inboundRateLimit.cfg.rate.toString()),
|
|
1474
|
-
}
|
|
1475
|
-
const cur =
|
|
1476
|
-
inboundRateLimiterState.tokens +
|
|
1477
|
-
inboundRateLimiterState.rate *
|
|
1478
|
-
BigInt(Math.floor(Date.now() / 1000) - base.inboundRateLimit.lastUpdated.toNumber())
|
|
1479
|
-
if (cur < inboundRateLimiterState.capacity) inboundRateLimiterState.tokens = cur
|
|
1480
|
-
else inboundRateLimiterState.tokens = inboundRateLimiterState.capacity
|
|
1481
|
-
}
|
|
1482
|
-
|
|
1483
|
-
let outboundRateLimiterState: RateLimiterState = null
|
|
1484
|
-
if (base.outboundRateLimit.cfg.enabled) {
|
|
1485
|
-
outboundRateLimiterState = {
|
|
1486
|
-
tokens: BigInt(base.outboundRateLimit.tokens.toString()),
|
|
1487
|
-
capacity: BigInt(base.outboundRateLimit.cfg.capacity.toString()),
|
|
1488
|
-
rate: BigInt(base.outboundRateLimit.cfg.rate.toString()),
|
|
1489
|
-
}
|
|
1490
|
-
const cur =
|
|
1491
|
-
outboundRateLimiterState.tokens +
|
|
1492
|
-
outboundRateLimiterState.rate *
|
|
1493
|
-
BigInt(Math.floor(Date.now() / 1000) - base.outboundRateLimit.lastUpdated.toNumber())
|
|
1494
|
-
if (cur < outboundRateLimiterState.capacity) outboundRateLimiterState.tokens = cur
|
|
1495
|
-
else outboundRateLimiterState.tokens = outboundRateLimiterState.capacity
|
|
1496
|
-
}
|
|
1421
|
+
const inboundRateLimiterState = convertRateLimiter(base.inboundRateLimit)
|
|
1422
|
+
const outboundRateLimiterState = convertRateLimiter(base.outboundRateLimit)
|
|
1497
1423
|
|
|
1498
1424
|
remotes[remoteNetwork.name] = {
|
|
1499
1425
|
remoteToken,
|