@across-protocol/sdk 4.1.63-beta.0 → 4.1.63-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/arch/svm/SpokeUtils.d.ts +3 -3
- package/dist/cjs/arch/svm/SpokeUtils.js +37 -41
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/constants.d.ts +1 -0
- package/dist/cjs/arch/svm/constants.js +3 -1
- package/dist/cjs/arch/svm/constants.js.map +1 -1
- package/dist/cjs/arch/svm/eventsClient.d.ts +6 -1
- package/dist/cjs/arch/svm/eventsClient.js +64 -0
- package/dist/cjs/arch/svm/eventsClient.js.map +1 -1
- package/dist/cjs/arch/svm/utils.js +2 -2
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/SuperstructUtils.d.ts +26 -26
- package/dist/cjs/interfaces/SpokePool.d.ts +6 -0
- package/dist/cjs/interfaces/SpokePool.js.map +1 -1
- package/dist/cjs/utils/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.d.ts +3 -3
- package/dist/esm/arch/svm/SpokeUtils.js +26 -30
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/constants.d.ts +1 -0
- package/dist/esm/arch/svm/constants.js +1 -0
- package/dist/esm/arch/svm/constants.js.map +1 -1
- package/dist/esm/arch/svm/eventsClient.d.ts +21 -1
- package/dist/esm/arch/svm/eventsClient.js +80 -1
- package/dist/esm/arch/svm/eventsClient.js.map +1 -1
- package/dist/esm/arch/svm/utils.js +3 -3
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/SuperstructUtils.d.ts +26 -26
- package/dist/esm/interfaces/SpokePool.d.ts +6 -0
- package/dist/esm/interfaces/SpokePool.js.map +1 -1
- package/dist/esm/utils/SpokeUtils.js.map +1 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts +3 -3
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/constants.d.ts +1 -0
- package/dist/types/arch/svm/constants.d.ts.map +1 -1
- package/dist/types/arch/svm/eventsClient.d.ts +21 -1
- package/dist/types/arch/svm/eventsClient.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/SuperstructUtils.d.ts +26 -26
- package/dist/types/interfaces/SpokePool.d.ts +6 -0
- package/dist/types/interfaces/SpokePool.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/arch/svm/SpokeUtils.ts +43 -43
- package/src/arch/svm/constants.ts +1 -0
- package/src/arch/svm/eventsClient.ts +114 -1
- package/src/arch/svm/utils.ts +4 -4
- package/src/interfaces/SpokePool.ts +7 -0
- package/src/utils/SpokeUtils.ts +2 -2
|
@@ -1,38 +1,41 @@
|
|
|
1
|
-
import {
|
|
2
|
-
SvmAddress,
|
|
3
|
-
getTokenInfo,
|
|
4
|
-
BigNumber,
|
|
5
|
-
isDefined,
|
|
6
|
-
isUnsafeDepositId,
|
|
7
|
-
toAddressType,
|
|
8
|
-
toBN,
|
|
9
|
-
getMessageHash,
|
|
10
|
-
keccak256,
|
|
11
|
-
chainIsSvm,
|
|
12
|
-
chunk,
|
|
13
|
-
} from "../../utils";
|
|
14
1
|
import { SvmSpokeClient } from "@across-protocol/contracts";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
2
|
+
import { decodeFillStatusAccount, fetchState } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke";
|
|
3
|
+
import { hashNonEmptyMessage } from "@across-protocol/contracts/dist/src/svm/web3-v1";
|
|
17
4
|
import {
|
|
18
|
-
TOKEN_PROGRAM_ADDRESS,
|
|
19
5
|
ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
6
|
+
TOKEN_PROGRAM_ADDRESS,
|
|
20
7
|
getApproveCheckedInstruction,
|
|
21
8
|
} from "@solana-program/token";
|
|
22
9
|
import {
|
|
23
10
|
Address,
|
|
24
|
-
some,
|
|
25
11
|
address,
|
|
26
|
-
getProgramDerivedAddress,
|
|
27
|
-
fetchEncodedAccounts,
|
|
28
12
|
fetchEncodedAccount,
|
|
13
|
+
fetchEncodedAccounts,
|
|
14
|
+
getAddressEncoder,
|
|
15
|
+
getProgramDerivedAddress,
|
|
16
|
+
getU32Encoder,
|
|
17
|
+
getU64Encoder,
|
|
18
|
+
some,
|
|
29
19
|
type TransactionSigner,
|
|
30
20
|
} from "@solana/kit";
|
|
31
21
|
import assert from "assert";
|
|
22
|
+
import { arrayify, hexZeroPad, hexlify } from "ethers/lib/utils";
|
|
32
23
|
import { Logger } from "winston";
|
|
33
|
-
import { fetchState, decodeFillStatusAccount } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke";
|
|
34
|
-
import { SVMEventNames, SVMProvider } from "./types";
|
|
35
24
|
import { CHAIN_IDs } from "../../constants";
|
|
25
|
+
import { Deposit, FillStatus, FillWithBlock, RelayData } from "../../interfaces";
|
|
26
|
+
import {
|
|
27
|
+
BigNumber,
|
|
28
|
+
SvmAddress,
|
|
29
|
+
chainIsSvm,
|
|
30
|
+
chunk,
|
|
31
|
+
getTokenInfo,
|
|
32
|
+
isDefined,
|
|
33
|
+
isUnsafeDepositId,
|
|
34
|
+
keccak256,
|
|
35
|
+
toAddressType,
|
|
36
|
+
} from "../../utils";
|
|
37
|
+
import { SvmCpiEventsClient, getEventAuthority, getFillStatusPda, getStatePda, unwrapEventData } from "./";
|
|
38
|
+
import { SVMEventNames, SVMProvider } from "./types";
|
|
36
39
|
|
|
37
40
|
/**
|
|
38
41
|
* @param spokePool SpokePool Contract instance.
|
|
@@ -412,29 +415,26 @@ export async function getAssociatedTokenAddress(
|
|
|
412
415
|
}
|
|
413
416
|
|
|
414
417
|
export function getRelayDataHash(relayData: RelayData, destinationChainId: number): string {
|
|
415
|
-
const
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
}
|
|
422
|
-
return littleEndian ? buffer.slice(0, byteLength).reverse() : buffer.slice(0, byteLength);
|
|
423
|
-
};
|
|
418
|
+
const addressEncoder = getAddressEncoder();
|
|
419
|
+
const uint64Encoder = getU64Encoder();
|
|
420
|
+
const uint32Encoder = getU32Encoder();
|
|
421
|
+
|
|
422
|
+
assert(relayData.message.startsWith("0x"), "Message must be a hex string");
|
|
423
|
+
|
|
424
424
|
const contentToHash = Buffer.concat([
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
425
|
+
Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.depositor, "base16").toV2Address())),
|
|
426
|
+
Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.recipient, "base16").toV2Address())),
|
|
427
|
+
Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.exclusiveRelayer, "base16").toV2Address())),
|
|
428
|
+
Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.inputToken, "base16").toV2Address())),
|
|
429
|
+
Uint8Array.from(addressEncoder.encode(SvmAddress.from(relayData.outputToken, "base16").toV2Address())),
|
|
430
|
+
Uint8Array.from(uint64Encoder.encode(BigInt(relayData.inputAmount.toString()))),
|
|
431
|
+
Uint8Array.from(uint64Encoder.encode(BigInt(relayData.outputAmount.toString()))),
|
|
432
|
+
Uint8Array.from(uint64Encoder.encode(BigInt(relayData.originChainId.toString()))),
|
|
433
|
+
arrayify(hexZeroPad(hexlify(relayData.depositId), 32)),
|
|
434
|
+
Uint8Array.from(uint32Encoder.encode(relayData.fillDeadline)),
|
|
435
|
+
Uint8Array.from(uint32Encoder.encode(relayData.exclusivityDeadline)),
|
|
436
|
+
hashNonEmptyMessage(Buffer.from(arrayify(relayData.message))),
|
|
437
|
+
Uint8Array.from(uint64Encoder.encode(BigInt(destinationChainId))),
|
|
438
438
|
]);
|
|
439
439
|
return keccak256(contentToHash);
|
|
440
440
|
}
|
|
@@ -2,9 +2,16 @@ import { Idl } from "@coral-xyz/anchor";
|
|
|
2
2
|
import { getDeployedAddress, SvmSpokeIdl } from "@across-protocol/contracts";
|
|
3
3
|
import { getSolanaChainId } from "@across-protocol/contracts/dist/src/svm/web3-v1";
|
|
4
4
|
import web3, { Address, Commitment, GetSignaturesForAddressApi, GetTransactionApi, Signature } from "@solana/kit";
|
|
5
|
-
import { bs58 } from "../../utils";
|
|
5
|
+
import { bs58, chainIsSvm, getMessageHash } from "../../utils";
|
|
6
6
|
import { EventName, EventWithData, SVMProvider } from "./types";
|
|
7
7
|
import { decodeEvent, isDevnet } from "./utils";
|
|
8
|
+
import { DepositWithTime, FillWithTime } from "../../interfaces";
|
|
9
|
+
import { unwrapEventData } from "./";
|
|
10
|
+
import assert from "assert";
|
|
11
|
+
import {
|
|
12
|
+
FundsDepositedEventObject,
|
|
13
|
+
FilledRelayEventObject,
|
|
14
|
+
} from "@across-protocol/contracts/dist/typechain/contracts/SpokePool";
|
|
8
15
|
|
|
9
16
|
// Utility type to extract the return type for the JSON encoding overload. We only care about the overload where the
|
|
10
17
|
// configuration parameter (C) has the optional property 'encoding' set to 'json'.
|
|
@@ -19,6 +26,9 @@ type GetSignaturesForAddressConfig = Parameters<GetSignaturesForAddressApi["getS
|
|
|
19
26
|
type GetSignaturesForAddressTransaction = ReturnType<GetSignaturesForAddressApi["getSignaturesForAddress"]>[number];
|
|
20
27
|
type GetSignaturesForAddressApiResponse = readonly GetSignaturesForAddressTransaction[];
|
|
21
28
|
|
|
29
|
+
export type DepositEventFromSignature = Omit<DepositWithTime, "fromLiteChain" | "toLiteChain">;
|
|
30
|
+
export type FillEventFromSignature = FillWithTime;
|
|
31
|
+
|
|
22
32
|
export class SvmCpiEventsClient {
|
|
23
33
|
private rpc: SVMProvider;
|
|
24
34
|
private programAddress: Address;
|
|
@@ -211,6 +221,109 @@ export class SvmCpiEventsClient {
|
|
|
211
221
|
return events;
|
|
212
222
|
}
|
|
213
223
|
|
|
224
|
+
/**
|
|
225
|
+
* Finds all FundsDeposited events for a given transaction signature.
|
|
226
|
+
*
|
|
227
|
+
* @param originChainId - The chain ID where the deposit originated.
|
|
228
|
+
* @param txSignature - The transaction signature to search for events.
|
|
229
|
+
* @param commitment - Optional commitment level for the transaction query.
|
|
230
|
+
* @returns A promise that resolves to an array of deposit events for the transaction, or undefined if none found.
|
|
231
|
+
*/
|
|
232
|
+
public async getDepositEventsFromSignature(
|
|
233
|
+
originChainId: number,
|
|
234
|
+
txSignature: Signature,
|
|
235
|
+
commitment: Commitment = "confirmed"
|
|
236
|
+
): Promise<DepositEventFromSignature[] | undefined> {
|
|
237
|
+
assert(chainIsSvm(originChainId), `Origin chain ${originChainId} is not an SVM chain`);
|
|
238
|
+
|
|
239
|
+
const [events, txDetails] = await Promise.all([
|
|
240
|
+
this.readEventsFromSignature(txSignature, commitment),
|
|
241
|
+
this.rpc
|
|
242
|
+
.getTransaction(txSignature, {
|
|
243
|
+
commitment,
|
|
244
|
+
maxSupportedTransactionVersion: 0,
|
|
245
|
+
})
|
|
246
|
+
.send(),
|
|
247
|
+
]);
|
|
248
|
+
|
|
249
|
+
// Filter for FundsDeposited events only
|
|
250
|
+
const depositEvents = events?.filter((event) => event?.name === "FundsDeposited");
|
|
251
|
+
|
|
252
|
+
if (!txDetails || !depositEvents?.length) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return events.map((event) => {
|
|
257
|
+
const unwrappedEventArgs = unwrapEventData(event as Record<string, unknown>, ["depositId"]) as Record<
|
|
258
|
+
"data",
|
|
259
|
+
FundsDepositedEventObject
|
|
260
|
+
>;
|
|
261
|
+
|
|
262
|
+
return {
|
|
263
|
+
...unwrappedEventArgs.data,
|
|
264
|
+
depositTimestamp: Number(txDetails.blockTime),
|
|
265
|
+
originChainId,
|
|
266
|
+
messageHash: getMessageHash(unwrappedEventArgs.data.message),
|
|
267
|
+
blockNumber: Number(txDetails.slot),
|
|
268
|
+
txnIndex: 0,
|
|
269
|
+
txnRef: txSignature,
|
|
270
|
+
logIndex: 0,
|
|
271
|
+
destinationChainId: unwrappedEventArgs.data.destinationChainId.toNumber(),
|
|
272
|
+
} satisfies DepositEventFromSignature;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Finds all FilledRelay events for a given transaction signature.
|
|
278
|
+
*
|
|
279
|
+
* @param destinationChainId - The destination chain ID (must be an SVM chain).
|
|
280
|
+
* @param txSignature - The transaction signature to search for events.
|
|
281
|
+
* @returns A promise that resolves to an array of fill events for the transaction, or undefined if none found.
|
|
282
|
+
*/
|
|
283
|
+
public async getFillEventsFromSignature(
|
|
284
|
+
destinationChainId: number,
|
|
285
|
+
txSignature: Signature,
|
|
286
|
+
commitment: Commitment = "confirmed"
|
|
287
|
+
): Promise<FillEventFromSignature[] | undefined> {
|
|
288
|
+
assert(chainIsSvm(destinationChainId), `Destination chain ${destinationChainId} is not an SVM chain`);
|
|
289
|
+
|
|
290
|
+
// Find all events from the transaction signature and get transaction details
|
|
291
|
+
const [events, txDetails] = await Promise.all([
|
|
292
|
+
this.readEventsFromSignature(txSignature, commitment),
|
|
293
|
+
this.rpc
|
|
294
|
+
.getTransaction(txSignature, {
|
|
295
|
+
commitment,
|
|
296
|
+
maxSupportedTransactionVersion: 0,
|
|
297
|
+
})
|
|
298
|
+
.send(),
|
|
299
|
+
]);
|
|
300
|
+
|
|
301
|
+
// Filter for FilledRelay events only
|
|
302
|
+
const fillEvents = events?.filter((event) => event?.name === "FilledRelay");
|
|
303
|
+
|
|
304
|
+
if (!txDetails || !fillEvents?.length) {
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return fillEvents.map((event) => {
|
|
309
|
+
const unwrappedEventData = unwrapEventData(event as Record<string, unknown>) as Record<
|
|
310
|
+
"data",
|
|
311
|
+
FilledRelayEventObject
|
|
312
|
+
>;
|
|
313
|
+
return {
|
|
314
|
+
...unwrappedEventData.data,
|
|
315
|
+
fillTimestamp: Number(txDetails.blockTime),
|
|
316
|
+
blockNumber: Number(txDetails.slot),
|
|
317
|
+
txnRef: txSignature,
|
|
318
|
+
txnIndex: 0,
|
|
319
|
+
logIndex: 0,
|
|
320
|
+
destinationChainId,
|
|
321
|
+
repaymentChainId: unwrappedEventData.data.repaymentChainId.toNumber(),
|
|
322
|
+
originChainId: unwrappedEventData.data.originChainId.toNumber(),
|
|
323
|
+
} satisfies FillEventFromSignature;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
214
327
|
public getProgramAddress(): Address {
|
|
215
328
|
return this.programAddress;
|
|
216
329
|
}
|
package/src/arch/svm/utils.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
+
import { SvmSpokeClient } from "@across-protocol/contracts";
|
|
1
2
|
import { BN, BorshEventCoder, Idl } from "@coral-xyz/anchor";
|
|
2
3
|
import {
|
|
4
|
+
Address,
|
|
3
5
|
address,
|
|
6
|
+
getAddressEncoder,
|
|
4
7
|
getProgramDerivedAddress,
|
|
5
8
|
getU64Encoder,
|
|
6
|
-
getAddressEncoder,
|
|
7
|
-
Address,
|
|
8
9
|
isAddress,
|
|
9
10
|
type TransactionSigner,
|
|
10
11
|
} from "@solana/kit";
|
|
11
|
-
import { BigNumber, getRelayDataHash, isUint8Array, SvmAddress } from "../../utils";
|
|
12
|
-
import { SvmSpokeClient } from "@across-protocol/contracts";
|
|
13
12
|
import { FillType, RelayData } from "../../interfaces";
|
|
13
|
+
import { BigNumber, SvmAddress, getRelayDataHash, isUint8Array } from "../../utils";
|
|
14
14
|
import { EventName, SVMEventNames, SVMProvider } from "./types";
|
|
15
15
|
|
|
16
16
|
/**
|
|
@@ -37,6 +37,10 @@ export interface DepositWithBlock extends Deposit, SortableEvent {
|
|
|
37
37
|
quoteBlockNumber: number;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
export interface DepositWithTime extends Deposit, SortableEvent {
|
|
41
|
+
depositTimestamp: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
export enum FillStatus {
|
|
41
45
|
Unfilled = 0,
|
|
42
46
|
RequestedSlowFill,
|
|
@@ -66,6 +70,9 @@ export interface Fill extends Omit<RelayData, "message"> {
|
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
export interface FillWithBlock extends Fill, SortableEvent {}
|
|
73
|
+
export interface FillWithTime extends Fill, SortableEvent {
|
|
74
|
+
fillTimestamp: number;
|
|
75
|
+
}
|
|
69
76
|
|
|
70
77
|
export interface EnabledDepositRoute {
|
|
71
78
|
originToken: string;
|
package/src/utils/SpokeUtils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { encodeAbiParameters, keccak256 } from "viem";
|
|
1
|
+
import { encodeAbiParameters, Hex, keccak256 } from "viem";
|
|
2
2
|
import { MAX_SAFE_DEPOSIT_ID, ZERO_ADDRESS, ZERO_BYTES } from "../constants";
|
|
3
3
|
import { Deposit, RelayData } from "../interfaces";
|
|
4
4
|
import { toBytes32 } from "./AddressUtils";
|
|
@@ -91,5 +91,5 @@ export function isZeroAddress(address: string): boolean {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
export function getMessageHash(message: string): string {
|
|
94
|
-
return isMessageEmpty(message) ? ZERO_BYTES : keccak256(message as
|
|
94
|
+
return isMessageEmpty(message) ? ZERO_BYTES : keccak256(message as Hex);
|
|
95
95
|
}
|