@across-protocol/sdk 4.1.63-beta.1 → 4.1.63-beta.3
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/evm/BlockUtils.d.ts +15 -0
- package/dist/cjs/arch/evm/BlockUtils.js +218 -0
- package/dist/cjs/arch/evm/BlockUtils.js.map +1 -0
- package/dist/cjs/arch/evm/index.d.ts +1 -0
- package/dist/cjs/arch/evm/index.js +1 -0
- package/dist/cjs/arch/evm/index.js.map +1 -1
- package/dist/cjs/arch/svm/SpokeUtils.d.ts +3 -2
- package/dist/cjs/arch/svm/SpokeUtils.js +42 -12
- package/dist/cjs/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/cjs/arch/svm/eventsClient.js +6 -6
- package/dist/cjs/arch/svm/eventsClient.js.map +1 -1
- package/dist/cjs/arch/svm/utils.d.ts +1 -0
- package/dist/cjs/arch/svm/utils.js +10 -2
- package/dist/cjs/arch/svm/utils.js.map +1 -1
- package/dist/cjs/clients/HubPoolClient.d.ts +3 -2
- package/dist/cjs/clients/HubPoolClient.js +2 -1
- package/dist/cjs/clients/HubPoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -1
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js +29 -2
- package/dist/cjs/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +4 -3
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.d.ts +33 -0
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js +184 -0
- package/dist/cjs/clients/mocks/MockSvmCpiEventsClient.js.map +1 -0
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.d.ts +30 -0
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js +90 -0
- package/dist/cjs/clients/mocks/MockSvmSpokePoolClient.js.map +1 -0
- package/dist/cjs/clients/mocks/index.d.ts +2 -0
- package/dist/cjs/clients/mocks/index.js +2 -0
- package/dist/cjs/clients/mocks/index.js.map +1 -1
- package/dist/cjs/constants.d.ts +1 -0
- package/dist/cjs/constants.js +2 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/providers/index.d.ts +1 -1
- package/dist/cjs/providers/index.js +1 -2
- package/dist/cjs/providers/index.js.map +1 -1
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.d.ts +5 -0
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js +21 -0
- package/dist/cjs/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -0
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.d.ts +5 -0
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js +20 -0
- package/dist/cjs/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -0
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.d.ts +13 -0
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js +76 -0
- package/dist/cjs/providers/mocks/MockSolanaRpcFactory.js.map +1 -0
- package/dist/cjs/providers/mocks/index.d.ts +4 -0
- package/dist/cjs/providers/mocks/index.js +8 -0
- package/dist/cjs/providers/mocks/index.js.map +1 -0
- package/dist/cjs/providers/{mockProvider.js → mocks/mockEthersProvider.js} +2 -2
- package/dist/cjs/providers/mocks/mockEthersProvider.js.map +1 -0
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js +5 -4
- package/dist/cjs/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.d.ts +9 -0
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.d.ts +6 -0
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js +69 -34
- package/dist/cjs/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.d.ts +11 -0
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js +9 -3
- package/dist/cjs/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/cjs/utils/BlockFinder.d.ts +22 -0
- package/dist/cjs/utils/BlockFinder.js +10 -0
- package/dist/cjs/utils/BlockFinder.js.map +1 -0
- package/dist/cjs/utils/BlockUtils.d.ts +2 -27
- package/dist/cjs/utils/BlockUtils.js +2 -208
- package/dist/cjs/utils/BlockUtils.js.map +1 -1
- package/dist/cjs/utils/TokenUtils.d.ts +18 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/index.js.map +1 -1
- package/dist/esm/arch/evm/BlockUtils.d.ts +24 -0
- package/dist/esm/arch/evm/BlockUtils.js +250 -0
- package/dist/esm/arch/evm/BlockUtils.js.map +1 -0
- package/dist/esm/arch/evm/index.d.ts +1 -0
- package/dist/esm/arch/evm/index.js +1 -0
- package/dist/esm/arch/evm/index.js.map +1 -1
- package/dist/esm/arch/svm/SpokeUtils.d.ts +37 -2
- package/dist/esm/arch/svm/SpokeUtils.js +80 -13
- package/dist/esm/arch/svm/SpokeUtils.js.map +1 -1
- package/dist/esm/arch/svm/eventsClient.js +6 -6
- package/dist/esm/arch/svm/eventsClient.js.map +1 -1
- package/dist/esm/arch/svm/utils.d.ts +4 -0
- package/dist/esm/arch/svm/utils.js +11 -1
- package/dist/esm/arch/svm/utils.js.map +1 -1
- package/dist/esm/clients/HubPoolClient.d.ts +3 -2
- package/dist/esm/clients/HubPoolClient.js +3 -2
- package/dist/esm/clients/HubPoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -2
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js +34 -5
- package/dist/esm/clients/SpokePoolClient/SVMSpokePoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +6 -4
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.d.ts +33 -0
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js +183 -0
- package/dist/esm/clients/mocks/MockSvmCpiEventsClient.js.map +1 -0
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.d.ts +30 -0
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js +89 -0
- package/dist/esm/clients/mocks/MockSvmSpokePoolClient.js.map +1 -0
- package/dist/esm/clients/mocks/index.d.ts +2 -0
- package/dist/esm/clients/mocks/index.js +2 -0
- package/dist/esm/clients/mocks/index.js.map +1 -1
- package/dist/esm/constants.d.ts +1 -0
- package/dist/esm/constants.js +1 -0
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/providers/index.d.ts +1 -1
- package/dist/esm/providers/index.js +1 -2
- package/dist/esm/providers/index.js.map +1 -1
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.d.ts +5 -0
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js +19 -0
- package/dist/esm/providers/mocks/MockCachedSolanaRpcFactory.js.map +1 -0
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.d.ts +5 -0
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js +18 -0
- package/dist/esm/providers/mocks/MockRateLimitedSolanaRpcFactory.js.map +1 -0
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.d.ts +13 -0
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js +74 -0
- package/dist/esm/providers/mocks/MockSolanaRpcFactory.js.map +1 -0
- package/dist/esm/providers/mocks/index.d.ts +4 -0
- package/dist/esm/providers/mocks/index.js +5 -0
- package/dist/esm/providers/mocks/index.js.map +1 -0
- package/dist/esm/providers/{mockProvider.js → mocks/mockEthersProvider.js} +2 -2
- package/dist/esm/providers/mocks/mockEthersProvider.js.map +1 -0
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js +6 -5
- package/dist/esm/relayFeeCalculator/chain-queries/baseQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/factory.d.ts +9 -0
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js +3 -3
- package/dist/esm/relayFeeCalculator/chain-queries/factory.js.map +1 -1
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.d.ts +18 -0
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js +83 -36
- package/dist/esm/relayFeeCalculator/chain-queries/svmQuery.js.map +1 -1
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.d.ts +21 -1
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js +9 -4
- package/dist/esm/relayFeeCalculator/relayFeeCalculator.js.map +1 -1
- package/dist/esm/utils/BlockFinder.d.ts +22 -0
- package/dist/esm/utils/BlockFinder.js +7 -0
- package/dist/esm/utils/BlockFinder.js.map +1 -0
- package/dist/esm/utils/BlockUtils.d.ts +2 -36
- package/dist/esm/utils/BlockUtils.js +2 -243
- package/dist/esm/utils/BlockUtils.js.map +1 -1
- package/dist/esm/utils/TokenUtils.d.ts +18 -0
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/types/arch/evm/BlockUtils.d.ts +25 -0
- package/dist/types/arch/evm/BlockUtils.d.ts.map +1 -0
- package/dist/types/arch/evm/index.d.ts +1 -0
- package/dist/types/arch/evm/index.d.ts.map +1 -1
- package/dist/types/arch/svm/SpokeUtils.d.ts +37 -2
- package/dist/types/arch/svm/SpokeUtils.d.ts.map +1 -1
- package/dist/types/arch/svm/eventsClient.d.ts.map +1 -1
- package/dist/types/arch/svm/utils.d.ts +4 -0
- package/dist/types/arch/svm/utils.d.ts.map +1 -1
- package/dist/types/clients/HubPoolClient.d.ts +3 -2
- package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
- package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts +1 -2
- package/dist/types/clients/SpokePoolClient/SVMSpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/mocks/MockSvmCpiEventsClient.d.ts +34 -0
- package/dist/types/clients/mocks/MockSvmCpiEventsClient.d.ts.map +1 -0
- package/dist/types/clients/mocks/MockSvmSpokePoolClient.d.ts +31 -0
- package/dist/types/clients/mocks/MockSvmSpokePoolClient.d.ts.map +1 -0
- package/dist/types/clients/mocks/index.d.ts +2 -0
- package/dist/types/clients/mocks/index.d.ts.map +1 -1
- package/dist/types/constants.d.ts +1 -0
- package/dist/types/constants.d.ts.map +1 -1
- package/dist/types/providers/index.d.ts +1 -1
- package/dist/types/providers/index.d.ts.map +1 -1
- package/dist/types/providers/mocks/MockCachedSolanaRpcFactory.d.ts +6 -0
- package/dist/types/providers/mocks/MockCachedSolanaRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/mocks/MockRateLimitedSolanaRpcFactory.d.ts +6 -0
- package/dist/types/providers/mocks/MockRateLimitedSolanaRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/mocks/MockSolanaRpcFactory.d.ts +14 -0
- package/dist/types/providers/mocks/MockSolanaRpcFactory.d.ts.map +1 -0
- package/dist/types/providers/mocks/index.d.ts +5 -0
- package/dist/types/providers/mocks/index.d.ts.map +1 -0
- package/dist/types/providers/{mockProvider.d.ts → mocks/mockEthersProvider.d.ts} +1 -1
- package/dist/types/providers/mocks/mockEthersProvider.d.ts.map +1 -0
- package/dist/types/relayFeeCalculator/chain-queries/baseQuery.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts +9 -0
- package/dist/types/relayFeeCalculator/chain-queries/factory.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts +18 -0
- package/dist/types/relayFeeCalculator/chain-queries/svmQuery.d.ts.map +1 -1
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts +21 -1
- package/dist/types/relayFeeCalculator/relayFeeCalculator.d.ts.map +1 -1
- package/dist/types/utils/BlockFinder.d.ts +23 -0
- package/dist/types/utils/BlockFinder.d.ts.map +1 -0
- package/dist/types/utils/BlockUtils.d.ts +2 -36
- package/dist/types/utils/BlockUtils.d.ts.map +1 -1
- package/dist/types/utils/TokenUtils.d.ts +18 -0
- package/dist/types/utils/TokenUtils.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/package.json +2 -3
- package/src/arch/evm/BlockUtils.ts +209 -0
- package/src/arch/evm/index.ts +1 -0
- package/src/arch/svm/SpokeUtils.ts +87 -17
- package/src/arch/svm/eventsClient.ts +13 -5
- package/src/arch/svm/utils.ts +12 -1
- package/src/clients/HubPoolClient.ts +3 -3
- package/src/clients/SpokePoolClient/SVMSpokePoolClient.ts +27 -3
- package/src/clients/SpokePoolClient/SpokePoolClient.ts +6 -3
- package/src/clients/mocks/MockSvmCpiEventsClient.ts +226 -0
- package/src/clients/mocks/MockSvmSpokePoolClient.ts +119 -0
- package/src/clients/mocks/index.ts +2 -0
- package/src/constants.ts +1 -0
- package/src/providers/index.ts +1 -1
- package/src/providers/mocks/MockCachedSolanaRpcFactory.ts +15 -0
- package/src/providers/mocks/MockRateLimitedSolanaRpcFactory.ts +14 -0
- package/src/providers/mocks/MockSolanaRpcFactory.ts +55 -0
- package/src/providers/mocks/index.ts +4 -0
- package/src/providers/{mockProvider.ts → mocks/mockEthersProvider.ts} +1 -1
- package/src/relayFeeCalculator/chain-queries/baseQuery.ts +6 -6
- package/src/relayFeeCalculator/chain-queries/factory.ts +3 -3
- package/src/relayFeeCalculator/chain-queries/svmQuery.ts +59 -27
- package/src/relayFeeCalculator/relayFeeCalculator.ts +15 -3
- package/src/utils/BlockFinder.ts +26 -0
- package/src/utils/BlockUtils.ts +5 -215
- package/src/utils/index.ts +1 -0
- package/dist/cjs/providers/mockProvider.js.map +0 -1
- package/dist/esm/providers/mockProvider.js.map +0 -1
- package/dist/types/providers/mockProvider.d.ts.map +0 -1
- /package/dist/cjs/providers/{mockProvider.d.ts → mocks/mockEthersProvider.d.ts} +0 -0
- /package/dist/esm/providers/{mockProvider.d.ts → mocks/mockEthersProvider.d.ts} +0 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import assert from "assert";
|
|
2
|
+
import { createHash } from "crypto";
|
|
3
|
+
import { hexlify, arrayify, hexZeroPad } from "ethers/lib/utils";
|
|
4
|
+
import { random } from "lodash";
|
|
5
|
+
import { Address, UnixTimestamp, signature } from "@solana/kit";
|
|
6
|
+
import { Idl } from "@coral-xyz/anchor";
|
|
7
|
+
import { SvmSpokeClient } from "@across-protocol/contracts";
|
|
8
|
+
import { CHAIN_IDs } from "@across-protocol/constants";
|
|
9
|
+
|
|
10
|
+
import { MockSolanaRpcFactory } from "../../providers/mocks";
|
|
11
|
+
import {
|
|
12
|
+
SVM_DEFAULT_ADDRESS,
|
|
13
|
+
EventName,
|
|
14
|
+
EventWithData,
|
|
15
|
+
SvmCpiEventsClient,
|
|
16
|
+
SVMEventNames,
|
|
17
|
+
SVMProvider,
|
|
18
|
+
getRandomSvmAddress,
|
|
19
|
+
} from "../../arch/svm";
|
|
20
|
+
import { bnZero, bnOne, bs58, getCurrentTime, randomAddress, EvmAddress } from "../../utils";
|
|
21
|
+
import { FillType } from "../../interfaces";
|
|
22
|
+
|
|
23
|
+
export class MockSvmCpiEventsClient extends SvmCpiEventsClient {
|
|
24
|
+
private events: Record<EventName, EventWithData[]> = {} as Record<EventName, EventWithData[]>;
|
|
25
|
+
private slotHeight: bigint = BigInt(0);
|
|
26
|
+
public chainId: number;
|
|
27
|
+
public minBlockRange = 10;
|
|
28
|
+
public numberOfDeposits = bnZero;
|
|
29
|
+
|
|
30
|
+
constructor(programId = SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS, chainId = CHAIN_IDs.SOLANA) {
|
|
31
|
+
super(null as unknown as SVMProvider, programId as Address, null as unknown as Address, null as unknown as Idl);
|
|
32
|
+
this.chainId = chainId;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public setSlotHeight(slotHeight: bigint) {
|
|
36
|
+
this.slotHeight = slotHeight;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public setEvents(events: EventWithData[]) {
|
|
40
|
+
for (const event of events) {
|
|
41
|
+
this.events[event.name as EventName] ??= [];
|
|
42
|
+
this.events[event.name as EventName].push(event);
|
|
43
|
+
}
|
|
44
|
+
const maxSlot = Math.max(...events.map((event) => Number(event.slot)));
|
|
45
|
+
this.setSlotHeight(BigInt(maxSlot) + BigInt(1));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public clearEvents(name?: EventName) {
|
|
49
|
+
if (name) {
|
|
50
|
+
this.events[name] = [];
|
|
51
|
+
} else {
|
|
52
|
+
this.events = {} as Record<EventName, EventWithData[]>;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public override queryEvents(eventName: EventName, fromSlot?: bigint, toSlot?: bigint): Promise<EventWithData[]> {
|
|
57
|
+
return Promise.resolve(
|
|
58
|
+
this.events[eventName]?.filter(
|
|
59
|
+
(event) => (!fromSlot || event.slot >= fromSlot) && (!toSlot || event.slot <= toSlot)
|
|
60
|
+
) ?? []
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
public override getRpc(): SVMProvider {
|
|
65
|
+
const client = new MockSolanaRpcFactory("https://test.com", 1234567890);
|
|
66
|
+
client.setResult("getSlot", [], this.slotHeight);
|
|
67
|
+
return client.createRpcClient();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
public deposit(deposit: SvmSpokeClient.FundsDeposited & Partial<EventWithData>): EventWithData {
|
|
71
|
+
const { slot } = deposit;
|
|
72
|
+
let { depositId, destinationChainId, inputAmount, outputAmount } = deposit;
|
|
73
|
+
depositId ??= arrayify(hexZeroPad(hexlify(random(1, 100_000, false)), 32));
|
|
74
|
+
this.numberOfDeposits = this.numberOfDeposits.add(bnOne);
|
|
75
|
+
|
|
76
|
+
destinationChainId ??= BigInt(random(1, 42161, false));
|
|
77
|
+
const depositor = deposit.depositor ?? getRandomSvmAddress();
|
|
78
|
+
const recipient = deposit.recipient ?? EvmAddress.from(randomAddress()).toBase58();
|
|
79
|
+
const inputToken = deposit.inputToken ?? getRandomSvmAddress();
|
|
80
|
+
const outputToken = deposit.outputToken ?? EvmAddress.from(randomAddress()).toBase58();
|
|
81
|
+
inputAmount ??= BigInt(random(1, 1000, false));
|
|
82
|
+
outputAmount ??= (inputAmount * BigInt(95)) / BigInt(100);
|
|
83
|
+
const message = deposit.message ?? new Uint8Array(32);
|
|
84
|
+
const quoteTimestamp = deposit.quoteTimestamp ?? getCurrentTime();
|
|
85
|
+
|
|
86
|
+
const args = {
|
|
87
|
+
depositId,
|
|
88
|
+
destinationChainId,
|
|
89
|
+
depositor,
|
|
90
|
+
recipient,
|
|
91
|
+
inputToken,
|
|
92
|
+
inputAmount,
|
|
93
|
+
outputToken,
|
|
94
|
+
outputAmount,
|
|
95
|
+
quoteTimestamp,
|
|
96
|
+
fillDeadline: deposit.fillDeadline ?? quoteTimestamp + 3600,
|
|
97
|
+
exclusiveRelayer: deposit.exclusiveRelayer ?? SVM_DEFAULT_ADDRESS,
|
|
98
|
+
exclusivityDeadline: deposit.exclusivityDeadline ?? quoteTimestamp + 600,
|
|
99
|
+
message,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return this.generateEvent({
|
|
103
|
+
event: SVMEventNames.FundsDeposited,
|
|
104
|
+
address: this.getProgramAddress(),
|
|
105
|
+
args,
|
|
106
|
+
slot,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public fillRelay(fill: SvmSpokeClient.FilledRelay & Partial<EventWithData>): EventWithData {
|
|
111
|
+
const { slot } = fill;
|
|
112
|
+
let { depositId, inputAmount, outputAmount, fillDeadline } = fill;
|
|
113
|
+
depositId ??= arrayify(hexZeroPad(hexlify(random(1, 100_000, false)), 32));
|
|
114
|
+
inputAmount ??= BigInt(random(1, 1000, false));
|
|
115
|
+
outputAmount ??= (inputAmount * BigInt(95)) / BigInt(100);
|
|
116
|
+
fillDeadline ??= getCurrentTime() + 60;
|
|
117
|
+
|
|
118
|
+
const depositor = fill.depositor ?? EvmAddress.from(randomAddress()).toBase58();
|
|
119
|
+
const recipient = fill.recipient ?? getRandomSvmAddress();
|
|
120
|
+
const inputToken = fill.inputToken ?? EvmAddress.from(randomAddress()).toBase58();
|
|
121
|
+
const outputToken = fill.outputToken ?? getRandomSvmAddress();
|
|
122
|
+
const messageHash = fill.messageHash ?? new Uint8Array(32);
|
|
123
|
+
|
|
124
|
+
const relayExecutionInfo = {
|
|
125
|
+
updatedRecipient: fill.relayExecutionInfo?.updatedRecipient ?? recipient,
|
|
126
|
+
updatedOutputAmount: fill.relayExecutionInfo?.updatedOutputAmount ?? outputAmount,
|
|
127
|
+
fillType: fill.relayExecutionInfo?.fillType ?? FillType.FastFill,
|
|
128
|
+
updatedMessageHash: fill.relayExecutionInfo?.updatedMessageHash ?? messageHash,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const args = {
|
|
132
|
+
depositId,
|
|
133
|
+
originChainId: fill.originChainId ?? BigInt(random(1, 42161, false)),
|
|
134
|
+
depositor,
|
|
135
|
+
recipient,
|
|
136
|
+
inputToken,
|
|
137
|
+
inputAmount,
|
|
138
|
+
outputToken,
|
|
139
|
+
outputAmount,
|
|
140
|
+
fillDeadline,
|
|
141
|
+
exclusiveRelayer: fill.exclusiveRelayer ?? SVM_DEFAULT_ADDRESS,
|
|
142
|
+
exclusivityDeadline: fill.exclusivityDeadline ?? fillDeadline,
|
|
143
|
+
relayer: fill.relayer ?? getRandomSvmAddress(),
|
|
144
|
+
messageHash,
|
|
145
|
+
relayExecutionInfo,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return this.generateEvent({
|
|
149
|
+
event: SVMEventNames.FilledRelay,
|
|
150
|
+
address: this.getProgramAddress(),
|
|
151
|
+
args,
|
|
152
|
+
slot,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public requestSlowFill(slowFillRequest: SvmSpokeClient.RequestedSlowFill & Partial<EventWithData>): EventWithData {
|
|
157
|
+
const { slot } = slowFillRequest;
|
|
158
|
+
let { depositId, originChainId } = slowFillRequest;
|
|
159
|
+
depositId ??= Uint8Array.from([random(1, 100_000, false)]);
|
|
160
|
+
originChainId ??= BigInt(random(1, 42161, false));
|
|
161
|
+
const depositor = slowFillRequest.depositor ?? EvmAddress.from(randomAddress()).toBase58();
|
|
162
|
+
const recipient = slowFillRequest.recipient ?? getRandomSvmAddress();
|
|
163
|
+
const inputToken = slowFillRequest.inputToken ?? EvmAddress.from(randomAddress()).toBase58();
|
|
164
|
+
const outputToken = slowFillRequest.outputToken ?? getRandomSvmAddress();
|
|
165
|
+
|
|
166
|
+
const args = {
|
|
167
|
+
...slowFillRequest,
|
|
168
|
+
depositId,
|
|
169
|
+
originChainId,
|
|
170
|
+
depositor,
|
|
171
|
+
recipient,
|
|
172
|
+
inputToken,
|
|
173
|
+
outputToken,
|
|
174
|
+
inputAmount: slowFillRequest.inputAmount ?? BigInt(random(1, 1000, false)),
|
|
175
|
+
outputAmount: slowFillRequest.outputAmount ?? slowFillRequest.inputAmount ?? BigInt(random(1, 1000, false)),
|
|
176
|
+
exclusiveRelayer: slowFillRequest.exclusiveRelayer ?? SVM_DEFAULT_ADDRESS,
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
return this.generateEvent({
|
|
180
|
+
event: SVMEventNames.RequestedSlowFill,
|
|
181
|
+
address: this.getProgramAddress(),
|
|
182
|
+
args,
|
|
183
|
+
slot,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
protected generateEvent(inputs: {
|
|
188
|
+
address: Address;
|
|
189
|
+
event: EventName;
|
|
190
|
+
args: Record<string, unknown>;
|
|
191
|
+
slot?: bigint;
|
|
192
|
+
}) {
|
|
193
|
+
const { address, event, args } = inputs;
|
|
194
|
+
let { slot } = inputs;
|
|
195
|
+
|
|
196
|
+
const randomSlotWithinRange = () =>
|
|
197
|
+
random(Number(this.slotHeight) + 1, Number(this.slotHeight) + this.minBlockRange, false);
|
|
198
|
+
|
|
199
|
+
// Increment the slot number by at least 1, by default. The caller may override
|
|
200
|
+
// to force the same slot number to be used, but never a previous slot number.
|
|
201
|
+
slot ??= BigInt(randomSlotWithinRange());
|
|
202
|
+
assert(slot >= this.slotHeight, `${slot} < ${this.slotHeight}`);
|
|
203
|
+
this.slotHeight = slot;
|
|
204
|
+
|
|
205
|
+
const generatedEvent = {
|
|
206
|
+
name: event,
|
|
207
|
+
slot,
|
|
208
|
+
signature: signature(
|
|
209
|
+
bs58.encode(
|
|
210
|
+
Uint8Array.from(
|
|
211
|
+
createHash("sha512")
|
|
212
|
+
.update(`Across-${event}-${slot}-${random(1, 100_000)}`)
|
|
213
|
+
.digest()
|
|
214
|
+
)
|
|
215
|
+
)
|
|
216
|
+
),
|
|
217
|
+
program: address,
|
|
218
|
+
data: args,
|
|
219
|
+
confirmationStatus: "finalized",
|
|
220
|
+
blockTime: BigInt(new Date().getTime()) as UnixTimestamp,
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
this.setEvents([generatedEvent]);
|
|
224
|
+
return generatedEvent;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import winston from "winston";
|
|
2
|
+
import { SvmSpokeClient } from "@across-protocol/contracts";
|
|
3
|
+
import { Address } from "@solana/kit";
|
|
4
|
+
import { DepositWithBlock, RelayerRefundExecution, SortableEvent, SlowFillLeaf, Log } from "../../interfaces";
|
|
5
|
+
import { getCurrentTime, bnZero, MakeOptional, EventSearchConfig } from "../../utils";
|
|
6
|
+
import { SpokePoolUpdate, SvmSpokePoolClient } from "../SpokePoolClient";
|
|
7
|
+
import { HubPoolClient } from "../HubPoolClient";
|
|
8
|
+
import { EventOverrides } from "./MockEvents";
|
|
9
|
+
import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
|
|
10
|
+
import { MockSvmCpiEventsClient } from "./MockSvmCpiEventsClient";
|
|
11
|
+
import { EventWithData, SvmCpiEventsClient, SVMEventNames, unwrapEventData } from "../../arch/svm";
|
|
12
|
+
|
|
13
|
+
// This class replaces internal SpokePoolClient functionality, enabling
|
|
14
|
+
// the user to bypass on-chain queries and inject events directly.
|
|
15
|
+
export class MockSvmSpokePoolClient extends SvmSpokePoolClient {
|
|
16
|
+
public mockEventsClient: MockSvmCpiEventsClient;
|
|
17
|
+
private destinationTokenForChainOverride: Record<number, string> = {};
|
|
18
|
+
|
|
19
|
+
constructor(
|
|
20
|
+
logger: winston.Logger,
|
|
21
|
+
chainId: number,
|
|
22
|
+
programId = SvmSpokeClient.SVM_SPOKE_PROGRAM_ADDRESS,
|
|
23
|
+
deploymentBlock: number = 1,
|
|
24
|
+
eventSearchConfig: MakeOptional<EventSearchConfig, "to"> = { from: 0, maxLookBack: 0 },
|
|
25
|
+
opts: { hubPoolClient: HubPoolClient | null } = { hubPoolClient: null }
|
|
26
|
+
) {
|
|
27
|
+
super(
|
|
28
|
+
logger,
|
|
29
|
+
opts.hubPoolClient,
|
|
30
|
+
chainId,
|
|
31
|
+
BigInt(deploymentBlock),
|
|
32
|
+
eventSearchConfig,
|
|
33
|
+
null as unknown as SvmCpiEventsClient,
|
|
34
|
+
programId,
|
|
35
|
+
null as unknown as Address
|
|
36
|
+
);
|
|
37
|
+
this.mockEventsClient = new MockSvmCpiEventsClient();
|
|
38
|
+
this.latestHeightSearched = deploymentBlock;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setConfigStoreClient(configStore?: AcrossConfigStoreClient): void {
|
|
42
|
+
this.configStoreClient = configStore;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
setDestinationTokenForChain(chainId: number, token: string): void {
|
|
46
|
+
this.destinationTokenForChainOverride[chainId] = token;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getDestinationTokenForDeposit(deposit: DepositWithBlock): string {
|
|
50
|
+
return this.destinationTokenForChainOverride[deposit.originChainId] ?? super.getDestinationTokenForDeposit(deposit);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setLatestBlockNumber(blockNumber: number): void {
|
|
54
|
+
this.latestHeightSearched = blockNumber;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async _update(eventsToQuery: string[]): Promise<SpokePoolUpdate> {
|
|
58
|
+
const from = this.eventSearchConfig.from ?? this.deploymentBlock;
|
|
59
|
+
const to = this.eventSearchConfig.to ? BigInt(this.eventSearchConfig.to) : undefined;
|
|
60
|
+
|
|
61
|
+
// Get events from the mock event client.
|
|
62
|
+
const events: EventWithData[][] = await Promise.all(
|
|
63
|
+
eventsToQuery.map((eventName) => this.mockEventsClient.queryEvents(eventName as SVMEventNames, BigInt(from), to))
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const eventsWithBlockNumber = events.map((eventList) =>
|
|
67
|
+
eventList.map((event) => {
|
|
68
|
+
return {
|
|
69
|
+
txnRef: event.signature,
|
|
70
|
+
blockNumber: Number(event.slot),
|
|
71
|
+
txnIndex: 0,
|
|
72
|
+
logIndex: 0,
|
|
73
|
+
...(unwrapEventData(event.data) as Record<string, unknown>),
|
|
74
|
+
};
|
|
75
|
+
})
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return Promise.resolve({
|
|
79
|
+
success: true,
|
|
80
|
+
firstDepositId: bnZero,
|
|
81
|
+
currentTime: getCurrentTime(),
|
|
82
|
+
events: eventsWithBlockNumber,
|
|
83
|
+
searchEndBlock: this.eventSearchConfig.to || this.latestHeightSearched,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
deposit(deposit: SvmSpokeClient.FundsDeposited & Partial<EventWithData>): EventWithData {
|
|
88
|
+
return this.mockEventsClient.deposit(deposit);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
fillRelay(fill: SvmSpokeClient.FilledRelay & Partial<EventWithData>): EventWithData {
|
|
92
|
+
return this.mockEventsClient.fillRelay(fill);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
requestSlowFill(request: SvmSpokeClient.RequestedSlowFill & Partial<EventWithData>): EventWithData {
|
|
96
|
+
return this.mockEventsClient.requestSlowFill(request);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
setTokensBridged(_tokensBridged: SvmSpokeClient.TokensBridged & Partial<EventWithData>): EventWithData {
|
|
100
|
+
throw new Error("MockSvmSpokePoolClient#setTokensBridged not implemented");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
executeSlowRelayLeaf(_leaf: Omit<SlowFillLeaf, "messageHash">): Log {
|
|
104
|
+
throw new Error("MockSvmSpokePoolClient#executeV3SlowRelayLeaf not implemented");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
executeRelayerRefundLeaf(_refund: RelayerRefundExecution & Partial<SortableEvent>): Log {
|
|
108
|
+
throw new Error("MockSvmSpokePoolClient#executeRelayerRefundLeaf not implemented");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
setEnableRoute(
|
|
112
|
+
_originToken: string,
|
|
113
|
+
_destinationChainId: number,
|
|
114
|
+
_enabled: boolean,
|
|
115
|
+
_overrides: EventOverrides = {}
|
|
116
|
+
): Log {
|
|
117
|
+
throw new Error("MockSvmSpokePoolClient#setEnableRoute not implemented");
|
|
118
|
+
}
|
|
119
|
+
}
|
package/src/constants.ts
CHANGED
|
@@ -54,6 +54,7 @@ export const DEFAULT_CACHING_TTL = 60 * 60 * 24 * 7 * 2; // 2 Weeks
|
|
|
54
54
|
export const DEFAULT_CACHING_SAFE_LAG = 60 * 60; // 1 hour
|
|
55
55
|
|
|
56
56
|
export const DEFAULT_SIMULATED_RELAYER_ADDRESS = "0x07aE8551Be970cB1cCa11Dd7a11F47Ae82e70E67";
|
|
57
|
+
export const DEFAULT_SIMULATED_RELAYER_ADDRESS_SVM = "FmMK62wrtWVb5SVoTZftSCGw3nEDA79hDbZNTRnC1R6t";
|
|
57
58
|
export const DEFAULT_SIMULATED_RELAYER_ADDRESS_TEST = "0x9A8f92a830A5cB89a3816e3D267CB7791c16b04D"; // Görli, ...
|
|
58
59
|
|
|
59
60
|
export const DEFAULT_ARWEAVE_STORAGE_ADDRESS = "Z6hjBM8FHu90lYWB8o5jR1dfX92FlV2WBaND9xgp8Lg";
|
package/src/providers/index.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CachedSolanaRpcFactory } from "..";
|
|
2
|
+
import { MockRateLimitedSolanaRpcFactory } from "./MockRateLimitedSolanaRpcFactory";
|
|
3
|
+
|
|
4
|
+
// Creates mocked cached Solana RPC factory by using the mocked Solana RPC factory.
|
|
5
|
+
export class MockCachedSolanaRpcFactory extends CachedSolanaRpcFactory {
|
|
6
|
+
constructor(
|
|
7
|
+
mockRateLimitedSolanaRpcFactory: MockRateLimitedSolanaRpcFactory,
|
|
8
|
+
...cachedConstructorParams: ConstructorParameters<typeof CachedSolanaRpcFactory>
|
|
9
|
+
) {
|
|
10
|
+
super(...cachedConstructorParams);
|
|
11
|
+
|
|
12
|
+
this.rateLimitedTransport = mockRateLimitedSolanaRpcFactory.createTransport();
|
|
13
|
+
this.rateLimitedRpcClient = mockRateLimitedSolanaRpcFactory.createRpcClient();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RateLimitedSolanaRpcFactory } from "..";
|
|
2
|
+
import { MockSolanaRpcFactory } from "./MockSolanaRpcFactory";
|
|
3
|
+
|
|
4
|
+
// Creates mocked rate limited Solana RPC factory by using the mocked Solana RPC factory.
|
|
5
|
+
export class MockRateLimitedSolanaRpcFactory extends RateLimitedSolanaRpcFactory {
|
|
6
|
+
constructor(
|
|
7
|
+
mockSolanaRpcFactory: MockSolanaRpcFactory,
|
|
8
|
+
...rateLimitedConstructorParams: ConstructorParameters<typeof RateLimitedSolanaRpcFactory>
|
|
9
|
+
) {
|
|
10
|
+
super(...rateLimitedConstructorParams);
|
|
11
|
+
|
|
12
|
+
this.defaultTransport = mockSolanaRpcFactory.createTransport();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { RpcResponse, RpcTransport } from "@solana/kit";
|
|
2
|
+
import { SolanaClusterRpcFactory } from "../solana";
|
|
3
|
+
|
|
4
|
+
type CachedResponse = { result: unknown } | { error: unknown } | { throwError: string };
|
|
5
|
+
|
|
6
|
+
// Exposes mocked RPC transport for Solana in the SolanaClusterRpcFactory class.
|
|
7
|
+
export class MockSolanaRpcFactory extends SolanaClusterRpcFactory {
|
|
8
|
+
private responseTime: number = 10; // in milliseconds
|
|
9
|
+
private responses: Map<string, CachedResponse> = new Map();
|
|
10
|
+
|
|
11
|
+
constructor(...clusterConstructorParams: ConstructorParameters<typeof SolanaClusterRpcFactory>) {
|
|
12
|
+
super(...clusterConstructorParams);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
public createTransport(): RpcTransport {
|
|
16
|
+
return <TResponse>(...args: Parameters<RpcTransport>): Promise<TResponse> => {
|
|
17
|
+
return this.createMockRpcTransport()<TResponse>(...args);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public setResult(method: string, params: unknown[], result: unknown) {
|
|
22
|
+
const requestKey = JSON.stringify({ method, params });
|
|
23
|
+
this.responses.set(requestKey, { result });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
public setError(method: string, params: unknown[], error: unknown) {
|
|
27
|
+
const requestKey = JSON.stringify({ method, params });
|
|
28
|
+
this.responses.set(requestKey, { error });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public setThrow(method: string, params: unknown[], throwError: string) {
|
|
32
|
+
const requestKey = JSON.stringify({ method, params });
|
|
33
|
+
this.responses.set(requestKey, { throwError });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
public setResponseTime(responseTime: number) {
|
|
37
|
+
this.responseTime = responseTime;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
private createMockRpcTransport(): RpcTransport {
|
|
41
|
+
return async <TResponse>({ payload }: Parameters<RpcTransport>[0]): Promise<RpcResponse<TResponse>> => {
|
|
42
|
+
const { method, params } = payload as { method: string; params?: unknown[] };
|
|
43
|
+
const requestKey = JSON.stringify({ method, params });
|
|
44
|
+
let jsonRpcResponse = this.responses.get(requestKey);
|
|
45
|
+
if (jsonRpcResponse === undefined) {
|
|
46
|
+
const requestKeyWithoutParams = JSON.stringify({ method, params: [] });
|
|
47
|
+
jsonRpcResponse = this.responses.get(requestKeyWithoutParams);
|
|
48
|
+
if (jsonRpcResponse === undefined) jsonRpcResponse = { result: null };
|
|
49
|
+
}
|
|
50
|
+
await new Promise((resolve) => setTimeout(resolve, this.responseTime));
|
|
51
|
+
if ("throwError" in jsonRpcResponse) throw new Error(jsonRpcResponse.throwError);
|
|
52
|
+
return jsonRpcResponse as TResponse;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BigNumber, providers } from "ethers";
|
|
2
2
|
import { Block, BlockTag, FeeData, TransactionResponse } from "@ethersproject/abstract-provider";
|
|
3
|
-
import { bnZero } from "
|
|
3
|
+
import { bnZero } from "../../utils/BigNumberUtils";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @notice Class used to test GasPriceOracle which makes ethers provider calls to the following implemented
|
|
@@ -3,7 +3,7 @@ import { isL2Provider as isOptimismL2Provider } from "@eth-optimism/sdk/dist/l2-
|
|
|
3
3
|
|
|
4
4
|
import { PopulatedTransaction, providers, VoidSigner } from "ethers";
|
|
5
5
|
import { Coingecko } from "../../coingecko";
|
|
6
|
-
import { CHAIN_IDs
|
|
6
|
+
import { CHAIN_IDs } from "../../constants";
|
|
7
7
|
import { Deposit } from "../../interfaces";
|
|
8
8
|
import { SpokePool, SpokePool__factory } from "../../typechain";
|
|
9
9
|
import { populateV3Relay } from "../../arch/evm";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
fixedPointAdjustment,
|
|
18
18
|
} from "../../utils";
|
|
19
19
|
import assert from "assert";
|
|
20
|
-
import { Logger, QueryInterface } from "../relayFeeCalculator";
|
|
20
|
+
import { Logger, QueryInterface, getDefaultSimulatedRelayerAddress } from "../relayFeeCalculator";
|
|
21
21
|
import { Transport } from "viem";
|
|
22
22
|
import { getGasPriceEstimate, EvmGasPriceEstimate } from "../../gasPriceOracle";
|
|
23
23
|
type Provider = providers.Provider;
|
|
@@ -72,7 +72,7 @@ export class QueryBase implements QueryInterface {
|
|
|
72
72
|
*/
|
|
73
73
|
async getGasCosts(
|
|
74
74
|
deposit: Omit<Deposit, "messageHash">,
|
|
75
|
-
relayer =
|
|
75
|
+
relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
|
|
76
76
|
options: Partial<{
|
|
77
77
|
gasPrice: BigNumberish;
|
|
78
78
|
gasUnits: BigNumberish;
|
|
@@ -122,7 +122,7 @@ export class QueryBase implements QueryInterface {
|
|
|
122
122
|
*/
|
|
123
123
|
getUnsignedTxFromDeposit(
|
|
124
124
|
deposit: Omit<Deposit, "messageHash">,
|
|
125
|
-
relayer =
|
|
125
|
+
relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId)
|
|
126
126
|
): Promise<PopulatedTransaction> {
|
|
127
127
|
return populateV3Relay(this.spokePool, deposit, relayer);
|
|
128
128
|
}
|
|
@@ -135,7 +135,7 @@ export class QueryBase implements QueryInterface {
|
|
|
135
135
|
*/
|
|
136
136
|
async getNativeGasCost(
|
|
137
137
|
deposit: Omit<Deposit, "messageHash">,
|
|
138
|
-
relayer =
|
|
138
|
+
relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId)
|
|
139
139
|
): Promise<BigNumber> {
|
|
140
140
|
const unsignedTx = await this.getUnsignedTxFromDeposit(deposit, relayer);
|
|
141
141
|
const voidSigner = new VoidSigner(relayer, this.provider);
|
|
@@ -152,7 +152,7 @@ export class QueryBase implements QueryInterface {
|
|
|
152
152
|
*/
|
|
153
153
|
async getOpStackL1DataFee(
|
|
154
154
|
unsignedTx: PopulatedTransaction,
|
|
155
|
-
relayer =
|
|
155
|
+
relayer = getDefaultSimulatedRelayerAddress(unsignedTx.chainId),
|
|
156
156
|
options: Partial<{
|
|
157
157
|
opStackL2GasUnits: BigNumberish;
|
|
158
158
|
opStackL1DataFeeMultiplier: BigNumber;
|
|
@@ -3,11 +3,11 @@ import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "@across-protocol/constants";
|
|
|
3
3
|
import { getDeployedAddress } from "@across-protocol/contracts";
|
|
4
4
|
import { asL2Provider } from "@eth-optimism/sdk";
|
|
5
5
|
import { providers } from "ethers";
|
|
6
|
-
import {
|
|
6
|
+
import { CUSTOM_GAS_TOKENS } from "../../constants";
|
|
7
7
|
import { chainIsOPStack, isDefined, chainIsSvm, SvmAddress } from "../../utils";
|
|
8
8
|
import { QueryBase } from "./baseQuery";
|
|
9
9
|
import { SVMProvider as svmProvider } from "../../arch/svm";
|
|
10
|
-
import { DEFAULT_LOGGER, Logger } from "../relayFeeCalculator";
|
|
10
|
+
import { DEFAULT_LOGGER, getDefaultSimulatedRelayerAddress, Logger } from "../relayFeeCalculator";
|
|
11
11
|
import { CustomGasTokenQueries } from "./customGasToken";
|
|
12
12
|
import { SvmQuery } from "./svmQuery";
|
|
13
13
|
|
|
@@ -25,7 +25,7 @@ export class QueryBase__factory {
|
|
|
25
25
|
provider: providers.Provider | svmProvider,
|
|
26
26
|
symbolMapping = TOKEN_SYMBOLS_MAP,
|
|
27
27
|
spokePoolAddress = getDeployedAddress("SpokePool", chainId),
|
|
28
|
-
simulatedRelayerAddress =
|
|
28
|
+
simulatedRelayerAddress = getDefaultSimulatedRelayerAddress(chainId),
|
|
29
29
|
coingeckoProApiKey?: string,
|
|
30
30
|
logger: Logger = DEFAULT_LOGGER,
|
|
31
31
|
coingeckoBaseCurrency = "eth"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pipe } from "@solana/functional";
|
|
2
2
|
import { Coingecko } from "../../coingecko";
|
|
3
3
|
import { SymbolMappingType } from "./";
|
|
4
|
-
import { CHAIN_IDs
|
|
4
|
+
import { CHAIN_IDs } from "../../constants";
|
|
5
5
|
import { Deposit } from "../../interfaces";
|
|
6
6
|
import { getGasPriceEstimate, SvmGasPriceEstimate } from "../../gasPriceOracle";
|
|
7
7
|
import {
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
isDefined,
|
|
14
14
|
toAddressType,
|
|
15
15
|
} from "../../utils";
|
|
16
|
-
import { Logger, QueryInterface } from "../relayFeeCalculator";
|
|
16
|
+
import { getDefaultSimulatedRelayerAddress, Logger, QueryInterface } from "../relayFeeCalculator";
|
|
17
17
|
import {
|
|
18
18
|
fillRelayInstruction,
|
|
19
19
|
createApproveInstruction,
|
|
@@ -79,7 +79,7 @@ export class SvmQuery implements QueryInterface {
|
|
|
79
79
|
*/
|
|
80
80
|
async getGasCosts(
|
|
81
81
|
deposit: Omit<Deposit, "messageHash">,
|
|
82
|
-
_relayer =
|
|
82
|
+
_relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId),
|
|
83
83
|
options: Partial<{
|
|
84
84
|
gasPrice: BigNumberish;
|
|
85
85
|
gasUnits: BigNumberish;
|
|
@@ -87,11 +87,64 @@ export class SvmQuery implements QueryInterface {
|
|
|
87
87
|
priorityFeeMultiplier: BigNumber;
|
|
88
88
|
}> = {}
|
|
89
89
|
): Promise<TransactionCostEstimate> {
|
|
90
|
+
const relayer = _relayer ? toAddressType(_relayer).forceSvmAddress() : this.simulatedRelayerAddress;
|
|
91
|
+
|
|
92
|
+
const fillRelayTx = await this.getFillRelayTx(deposit, relayer.toBase58());
|
|
93
|
+
|
|
94
|
+
const [computeUnitsConsumed, _gasPriceEstimate] = await Promise.all([
|
|
95
|
+
toBN(await this.computeUnitEstimator(fillRelayTx)),
|
|
96
|
+
getGasPriceEstimate(this.provider, {
|
|
97
|
+
unsignedTx: fillRelayTx,
|
|
98
|
+
baseFeeMultiplier: options.baseFeeMultiplier,
|
|
99
|
+
priorityFeeMultiplier: options.priorityFeeMultiplier,
|
|
100
|
+
}),
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
// We can cast the gas price estimate to an SvmGasPriceEstimate here since the oracle should always
|
|
104
|
+
// query the Solana adapter.
|
|
105
|
+
const gasPriceEstimate = _gasPriceEstimate as SvmGasPriceEstimate;
|
|
106
|
+
const gasPrice = gasPriceEstimate.baseFee.add(
|
|
107
|
+
gasPriceEstimate.microLamportsPerComputeUnit.mul(computeUnitsConsumed).div(toBN(1_000_000)) // 1_000_000 microLamports/lamport.
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
nativeGasCost: computeUnitsConsumed,
|
|
112
|
+
tokenGasCost: gasPrice,
|
|
113
|
+
gasPrice,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* @notice Return the gas cost of a simulated transaction
|
|
119
|
+
* @param fillRelayTx FillRelay transaction
|
|
120
|
+
* @param relayer SVM address of the relayer
|
|
121
|
+
* @returns Estimated gas cost in compute units
|
|
122
|
+
*/
|
|
123
|
+
async getNativeGasCost(
|
|
124
|
+
deposit: Omit<Deposit, "messageHash">,
|
|
125
|
+
_relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId)
|
|
126
|
+
): Promise<BigNumber> {
|
|
127
|
+
const fillRelayTx = await this.getFillRelayTx(deposit, _relayer);
|
|
128
|
+
const computeUnitsConsumed = toBN(await this.computeUnitEstimator(fillRelayTx));
|
|
129
|
+
return computeUnitsConsumed;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @notice Return the fillRelay transaction for a given deposit
|
|
134
|
+
* @param deposit
|
|
135
|
+
* @param relayer SVM address of the relayer
|
|
136
|
+
* @returns FillRelay transaction
|
|
137
|
+
*/
|
|
138
|
+
async getFillRelayTx(
|
|
139
|
+
deposit: Omit<Deposit, "messageHash">,
|
|
140
|
+
_relayer = getDefaultSimulatedRelayerAddress(deposit.destinationChainId)
|
|
141
|
+
) {
|
|
142
|
+
const relayer = _relayer ? toAddressType(_relayer).forceSvmAddress() : this.simulatedRelayerAddress;
|
|
90
143
|
// If the user did not have a token account created on destination, then we need to include this as a gas cost.
|
|
91
144
|
const mint = toAddressType(deposit.outputToken).forceSvmAddress();
|
|
92
145
|
const owner = toAddressType(deposit.recipient).forceSvmAddress();
|
|
93
146
|
const associatedToken = await getAssociatedTokenAddress(owner, mint);
|
|
94
|
-
const simulatedSigner = SolanaVoidSigner(
|
|
147
|
+
const simulatedSigner = SolanaVoidSigner(relayer.toBase58());
|
|
95
148
|
|
|
96
149
|
// If the recipient has an associated token account on destination, then skip generating the instruction for creating a new token account.
|
|
97
150
|
let recipientCreateTokenAccountInstructions: IInstruction[] | undefined = undefined;
|
|
@@ -134,7 +187,7 @@ export class SvmQuery implements QueryInterface {
|
|
|
134
187
|
const recentBlockhash = await this.provider.getLatestBlockhash().send();
|
|
135
188
|
const fillRelayTx = pipe(
|
|
136
189
|
createTransactionMessage({ version: 0 }),
|
|
137
|
-
(tx) => setTransactionMessageFeePayer(
|
|
190
|
+
(tx) => setTransactionMessageFeePayer(relayer.toV2Address(), tx),
|
|
138
191
|
(tx) => setTransactionMessageLifetimeUsingBlockhash(recentBlockhash.value, tx),
|
|
139
192
|
(tx) =>
|
|
140
193
|
isDefined(recipientCreateTokenAccountInstructions)
|
|
@@ -142,28 +195,7 @@ export class SvmQuery implements QueryInterface {
|
|
|
142
195
|
: tx,
|
|
143
196
|
(tx) => appendTransactionMessageInstructions([createTokenAccountsIx, approveIx, fillIx], tx)
|
|
144
197
|
);
|
|
145
|
-
|
|
146
|
-
const [computeUnitsConsumed, _gasPriceEstimate] = await Promise.all([
|
|
147
|
-
toBN(await this.computeUnitEstimator(fillRelayTx)),
|
|
148
|
-
getGasPriceEstimate(this.provider, {
|
|
149
|
-
unsignedTx: fillRelayTx,
|
|
150
|
-
baseFeeMultiplier: options.baseFeeMultiplier,
|
|
151
|
-
priorityFeeMultiplier: options.priorityFeeMultiplier,
|
|
152
|
-
}),
|
|
153
|
-
]);
|
|
154
|
-
|
|
155
|
-
// We can cast the gas price estimate to an SvmGasPriceEstimate here since the oracle should always
|
|
156
|
-
// query the Solana adapter.
|
|
157
|
-
const gasPriceEstimate = _gasPriceEstimate as SvmGasPriceEstimate;
|
|
158
|
-
const gasPrice = gasPriceEstimate.baseFee.add(
|
|
159
|
-
gasPriceEstimate.microLamportsPerComputeUnit.mul(computeUnitsConsumed).div(toBN(1_000_000)) // 1_000_000 microLamports/lamport.
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
nativeGasCost: computeUnitsConsumed,
|
|
164
|
-
tokenGasCost: gasPrice,
|
|
165
|
-
gasPrice,
|
|
166
|
-
};
|
|
198
|
+
return fillRelayTx;
|
|
167
199
|
}
|
|
168
200
|
|
|
169
201
|
/**
|