@across-protocol/sdk 4.1.44 → 4.1.45-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/clients/BundleDataClient/BundleDataClient.js +23 -14
- package/dist/cjs/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js +10 -1
- package/dist/cjs/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.d.ts +7 -7
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js +47 -36
- package/dist/cjs/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
- package/dist/cjs/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/cjs/clients/HubPoolClient.d.ts +3 -2
- package/dist/cjs/clients/HubPoolClient.js +27 -15
- package/dist/cjs/clients/HubPoolClient.js.map +1 -1
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js +19 -5
- package/dist/cjs/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/cjs/clients/mocks/MockHubPoolClient.d.ts +2 -0
- package/dist/cjs/clients/mocks/MockHubPoolClient.js +18 -0
- package/dist/cjs/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/cjs/svm/eventsClient.js +5 -12
- package/dist/cjs/svm/eventsClient.js.map +1 -1
- package/dist/cjs/svm/index.d.ts +2 -0
- package/dist/cjs/svm/index.js +3 -0
- package/dist/cjs/svm/index.js.map +1 -1
- package/dist/cjs/svm/utils/events.d.ts +6 -1
- package/dist/cjs/svm/utils/events.js +13 -4
- package/dist/cjs/svm/utils/events.js.map +1 -1
- package/dist/cjs/svm/utils/index.d.ts +1 -0
- package/dist/cjs/svm/utils/index.js +5 -0
- package/dist/cjs/svm/utils/index.js.map +1 -0
- package/dist/cjs/utils/DepositUtils.d.ts +1 -0
- package/dist/cjs/utils/DepositUtils.js +5 -1
- package/dist/cjs/utils/DepositUtils.js.map +1 -1
- package/dist/cjs/utils/common.d.ts +2 -0
- package/dist/cjs/utils/common.js +3 -1
- package/dist/cjs/utils/common.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js +24 -15
- package/dist/esm/clients/BundleDataClient/BundleDataClient.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js +16 -1
- package/dist/esm/clients/BundleDataClient/utils/DataworkerUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.d.ts +28 -7
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js +83 -50
- package/dist/esm/clients/BundleDataClient/utils/FillUtils.js.map +1 -1
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js +2 -2
- package/dist/esm/clients/BundleDataClient/utils/PoolRebalanceUtils.js.map +1 -1
- package/dist/esm/clients/HubPoolClient.d.ts +3 -16
- package/dist/esm/clients/HubPoolClient.js +31 -33
- package/dist/esm/clients/HubPoolClient.js.map +1 -1
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js +28 -14
- package/dist/esm/clients/SpokePoolClient/SpokePoolClient.js.map +1 -1
- package/dist/esm/clients/mocks/MockHubPoolClient.d.ts +2 -0
- package/dist/esm/clients/mocks/MockHubPoolClient.js +18 -0
- package/dist/esm/clients/mocks/MockHubPoolClient.js.map +1 -1
- package/dist/esm/svm/eventsClient.js +6 -13
- package/dist/esm/svm/eventsClient.js.map +1 -1
- package/dist/esm/svm/index.d.ts +2 -0
- package/dist/esm/svm/index.js +3 -0
- package/dist/esm/svm/index.js.map +1 -1
- package/dist/esm/svm/utils/events.d.ts +9 -1
- package/dist/esm/svm/utils/events.js +15 -3
- package/dist/esm/svm/utils/events.js.map +1 -1
- package/dist/esm/svm/utils/index.d.ts +1 -0
- package/dist/esm/svm/utils/index.js +2 -0
- package/dist/esm/svm/utils/index.js.map +1 -0
- package/dist/esm/utils/DepositUtils.d.ts +1 -0
- package/dist/esm/utils/DepositUtils.js +5 -1
- package/dist/esm/utils/DepositUtils.js.map +1 -1
- package/dist/esm/utils/common.d.ts +2 -0
- package/dist/esm/utils/common.js +2 -0
- package/dist/esm/utils/common.js.map +1 -1
- package/dist/types/clients/BundleDataClient/BundleDataClient.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/DataworkerUtils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts +28 -7
- package/dist/types/clients/BundleDataClient/utils/FillUtils.d.ts.map +1 -1
- package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts +1 -1
- package/dist/types/clients/BundleDataClient/utils/PoolRebalanceUtils.d.ts.map +1 -1
- package/dist/types/clients/HubPoolClient.d.ts +3 -16
- package/dist/types/clients/HubPoolClient.d.ts.map +1 -1
- package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts +1 -0
- package/dist/types/clients/SpokePoolClient/SpokePoolClient.d.ts.map +1 -1
- package/dist/types/clients/mocks/MockHubPoolClient.d.ts +2 -0
- package/dist/types/clients/mocks/MockHubPoolClient.d.ts.map +1 -1
- package/dist/types/svm/eventsClient.d.ts.map +1 -1
- package/dist/types/svm/index.d.ts +2 -0
- package/dist/types/svm/index.d.ts.map +1 -1
- package/dist/types/svm/utils/events.d.ts +9 -1
- package/dist/types/svm/utils/events.d.ts.map +1 -1
- package/dist/types/svm/utils/index.d.ts +2 -0
- package/dist/types/svm/utils/index.d.ts.map +1 -0
- package/dist/types/utils/DepositUtils.d.ts +1 -0
- package/dist/types/utils/DepositUtils.d.ts.map +1 -1
- package/dist/types/utils/common.d.ts +2 -0
- package/dist/types/utils/common.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/clients/BundleDataClient/BundleDataClient.ts +38 -21
- package/src/clients/BundleDataClient/utils/DataworkerUtils.ts +36 -1
- package/src/clients/BundleDataClient/utils/FillUtils.ts +133 -71
- package/src/clients/BundleDataClient/utils/PoolRebalanceUtils.ts +3 -2
- package/src/clients/HubPoolClient.ts +41 -38
- package/src/clients/SpokePoolClient/SpokePoolClient.ts +54 -16
- package/src/clients/mocks/MockHubPoolClient.ts +16 -0
- package/src/svm/eventsClient.ts +6 -12
- package/src/svm/index.ts +2 -0
- package/src/svm/utils/events.ts +16 -4
- package/src/svm/utils/index.ts +1 -0
- package/src/utils/DepositUtils.ts +6 -1
- package/src/utils/common.ts +2 -0
|
@@ -163,12 +163,13 @@ export function updateRunningBalanceForDeposit(
|
|
|
163
163
|
runningBalances: RunningBalances,
|
|
164
164
|
hubPoolClient: HubPoolClient,
|
|
165
165
|
deposit: V3DepositWithBlock,
|
|
166
|
-
updateAmount: BigNumber
|
|
166
|
+
updateAmount: BigNumber,
|
|
167
|
+
mainnetBundleEndBlock: number
|
|
167
168
|
): void {
|
|
168
169
|
const l1TokenCounterpart = hubPoolClient.getL1TokenForL2TokenAtBlock(
|
|
169
170
|
deposit.inputToken,
|
|
170
171
|
deposit.originChainId,
|
|
171
|
-
|
|
172
|
+
mainnetBundleEndBlock
|
|
172
173
|
);
|
|
173
174
|
updateRunningBalance(runningBalances, deposit.originChainId, l1TokenCounterpart, updateAmount);
|
|
174
175
|
}
|
|
@@ -231,40 +231,41 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
231
231
|
return sortEventsDescending(l2Tokens)[0].l1Token;
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
* at the HubPool equivalent block number of the L2 event.
|
|
238
|
-
* @param deposit Deposit event
|
|
239
|
-
* @param returns string L1 token counterpart for Deposit
|
|
240
|
-
*/
|
|
241
|
-
getL1TokenForDeposit(deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber">): string {
|
|
234
|
+
protected getL1TokenForDeposit(
|
|
235
|
+
deposit: Pick<DepositWithBlock, "originChainId" | "inputToken" | "quoteBlockNumber">
|
|
236
|
+
): string {
|
|
242
237
|
// L1-->L2 token mappings are set via PoolRebalanceRoutes which occur on mainnet,
|
|
243
238
|
// so we use the latest token mapping. This way if a very old deposit is filled, the relayer can use the
|
|
244
239
|
// latest L2 token mapping to find the L1 token counterpart.
|
|
245
240
|
return this.getL1TokenForL2TokenAtBlock(deposit.inputToken, deposit.originChainId, deposit.quoteBlockNumber);
|
|
246
241
|
}
|
|
247
242
|
|
|
248
|
-
/**
|
|
249
|
-
* Returns the L2 token that should be used as a counterpart to a deposit event. For example, the caller
|
|
250
|
-
* might want to know what the refund token will be on l2ChainId for the deposit event.
|
|
251
|
-
* @param l2ChainId Chain where caller wants to get L2 token counterpart for
|
|
252
|
-
* @param event Deposit event
|
|
253
|
-
* @returns string L2 token counterpart on l2ChainId
|
|
254
|
-
*/
|
|
255
|
-
getL2TokenForDeposit(
|
|
256
|
-
deposit: Pick<DepositWithBlock, "originChainId" | "destinationChainId" | "inputToken" | "quoteBlockNumber">,
|
|
257
|
-
l2ChainId = deposit.destinationChainId
|
|
258
|
-
): string {
|
|
259
|
-
const l1Token = this.getL1TokenForDeposit(deposit);
|
|
260
|
-
// Use the latest hub block number to find the L2 token counterpart.
|
|
261
|
-
return this.getL2TokenForL1TokenAtBlock(l1Token, l2ChainId, deposit.quoteBlockNumber);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
243
|
l2TokenEnabledForL1Token(l1Token: string, destinationChainId: number): boolean {
|
|
265
244
|
return this.l1TokensToDestinationTokens?.[l1Token]?.[destinationChainId] != undefined;
|
|
266
245
|
}
|
|
267
246
|
|
|
247
|
+
l2TokenEnabledForL1TokenAtBlock(l1Token: string, destinationChainId: number, hubBlockNumber: number): boolean {
|
|
248
|
+
// Find the last mapping published before the target block.
|
|
249
|
+
const l2Token: DestinationTokenWithBlock | undefined = sortEventsDescending(
|
|
250
|
+
this.l1TokensToDestinationTokensWithBlock?.[l1Token]?.[destinationChainId] ?? []
|
|
251
|
+
).find((mapping: DestinationTokenWithBlock) => mapping.blockNumber <= hubBlockNumber);
|
|
252
|
+
return l2Token !== undefined;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
l2TokenHasPoolRebalanceRoute(l2Token: string, l2ChainId: number, hubPoolBlock = this.latestBlockSearched): boolean {
|
|
256
|
+
return Object.values(this.l1TokensToDestinationTokensWithBlock).some((destinationTokenMapping) => {
|
|
257
|
+
return Object.entries(destinationTokenMapping).some(([_l2ChainId, setPoolRebalanceRouteEvents]) => {
|
|
258
|
+
return setPoolRebalanceRouteEvents.some((e) => {
|
|
259
|
+
return (
|
|
260
|
+
e.blockNumber <= hubPoolBlock &&
|
|
261
|
+
compareAddressesSimple(e.l2Token, l2Token) &&
|
|
262
|
+
Number(_l2ChainId) === l2ChainId
|
|
263
|
+
);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
|
|
268
269
|
/**
|
|
269
270
|
* @dev If tokenAddress + chain do not exist in TOKEN_SYMBOLS_MAP then this will throw.
|
|
270
271
|
* @param tokenAddress Token address on `chain`
|
|
@@ -529,21 +530,23 @@ export class HubPoolClient extends BaseAbstractClient {
|
|
|
529
530
|
chainIdB: number,
|
|
530
531
|
hubPoolBlock = this.latestBlockSearched
|
|
531
532
|
): boolean {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
return false;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
// Resolve both HubPool tokens back to a current SpokePool token and verify that they match.
|
|
541
|
-
const _tokenA = this.getL2TokenForL1TokenAtBlock(l1TokenA, chainIdA, hubPoolBlock);
|
|
542
|
-
const _tokenB = this.getL2TokenForL1TokenAtBlock(l1TokenB, chainIdB, hubPoolBlock);
|
|
543
|
-
return tokenA === _tokenA && tokenB === _tokenB;
|
|
544
|
-
} catch {
|
|
545
|
-
return false; // One or both input tokens were not recognised.
|
|
533
|
+
if (
|
|
534
|
+
!this.l2TokenHasPoolRebalanceRoute(tokenA, chainIdA, hubPoolBlock) ||
|
|
535
|
+
!this.l2TokenHasPoolRebalanceRoute(tokenB, chainIdB, hubPoolBlock)
|
|
536
|
+
) {
|
|
537
|
+
return false;
|
|
546
538
|
}
|
|
539
|
+
// Resolve both SpokePool tokens back to their respective HubPool tokens and verify that they match.
|
|
540
|
+
const l1TokenA = this.getL1TokenForL2TokenAtBlock(tokenA, chainIdA, hubPoolBlock);
|
|
541
|
+
const l1TokenB = this.getL1TokenForL2TokenAtBlock(tokenB, chainIdB, hubPoolBlock);
|
|
542
|
+
if (l1TokenA !== l1TokenB) {
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// Resolve both HubPool tokens back to a current SpokePool token and verify that they match.
|
|
547
|
+
const _tokenA = this.getL2TokenForL1TokenAtBlock(l1TokenA, chainIdA, hubPoolBlock);
|
|
548
|
+
const _tokenB = this.getL2TokenForL1TokenAtBlock(l1TokenB, chainIdB, hubPoolBlock);
|
|
549
|
+
return tokenA === _tokenA && tokenB === _tokenB;
|
|
547
550
|
}
|
|
548
551
|
|
|
549
552
|
getSpokeActivationBlockForChain(chainId: number): number {
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
isZeroAddress,
|
|
18
18
|
toAddress,
|
|
19
19
|
validateFillForDeposit,
|
|
20
|
+
chainIsEvm,
|
|
20
21
|
} from "../../utils";
|
|
21
22
|
import {
|
|
22
23
|
duplicateEvent,
|
|
@@ -41,7 +42,7 @@ import {
|
|
|
41
42
|
} from "../../interfaces";
|
|
42
43
|
import { BaseAbstractClient, UpdateFailureReason } from "../BaseAbstractClient";
|
|
43
44
|
import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
|
|
44
|
-
import {
|
|
45
|
+
import { getRefundInformationFromFill } from "../BundleDataClient";
|
|
45
46
|
import { HubPoolClient } from "../HubPoolClient";
|
|
46
47
|
|
|
47
48
|
export type SpokePoolUpdateSuccess = {
|
|
@@ -365,22 +366,25 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
365
366
|
fill: FillWithBlock
|
|
366
367
|
) => {
|
|
367
368
|
if (validateFillForDeposit(fill, deposit).valid) {
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
369
|
+
const fillRepaymentData = {
|
|
370
|
+
...fill,
|
|
371
|
+
fromLiteChain: deposit.fromLiteChain,
|
|
372
|
+
};
|
|
373
|
+
const { chainToSendRefundTo: repaymentChainId } = getRefundInformationFromFill(
|
|
374
|
+
fillRepaymentData,
|
|
375
|
+
this.hubPoolClient!,
|
|
376
|
+
this.hubPoolClient!.latestBlockSearched
|
|
377
|
+
);
|
|
378
|
+
// In order to keep this function sync, we can't call verifyFillRepayment so we'll log any fills where
|
|
379
|
+
// the filler-specified repayment chain and repayment address is not a valid repayment upon
|
|
380
|
+
// first glance. In other words, the repayment address is not a valid EVM address or the repayment chain
|
|
381
|
+
// is not a valid EVM chain. In the case where the repayment address is not a valid EVM address, the dataworker
|
|
382
|
+
// might be able to overwrite the repayment address to the msg.sender on the fill txn, but to keep this
|
|
383
|
+
// functioon synchronous, we can't make that decision now. So this function might log some false positives.
|
|
375
384
|
if (
|
|
376
385
|
this.hubPoolClient &&
|
|
377
386
|
!isSlowFill(fill) &&
|
|
378
|
-
(!isValidEvmAddress(fill.relayer)
|
|
379
|
-
forceDestinationRepayment(
|
|
380
|
-
repaymentChainId,
|
|
381
|
-
{ ...deposit, quoteBlockNumber: this.hubPoolClient!.latestBlockSearched },
|
|
382
|
-
this.hubPoolClient
|
|
383
|
-
))
|
|
387
|
+
(!chainIsEvm(repaymentChainId) || !isValidEvmAddress(fill.relayer))
|
|
384
388
|
) {
|
|
385
389
|
groupedFills.unrepayableFills.push(fill);
|
|
386
390
|
}
|
|
@@ -450,6 +454,29 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
450
454
|
return `${event.depositId.toString()}-${event.originChainId}`;
|
|
451
455
|
}
|
|
452
456
|
|
|
457
|
+
protected canResolveZeroAddressOutputToken(deposit: DepositWithBlock): boolean {
|
|
458
|
+
if (
|
|
459
|
+
!this.hubPoolClient?.l2TokenHasPoolRebalanceRoute(
|
|
460
|
+
deposit.inputToken,
|
|
461
|
+
deposit.originChainId,
|
|
462
|
+
deposit.quoteBlockNumber
|
|
463
|
+
)
|
|
464
|
+
) {
|
|
465
|
+
return false;
|
|
466
|
+
} else {
|
|
467
|
+
const l1Token = this.hubPoolClient?.getL1TokenForL2TokenAtBlock(
|
|
468
|
+
deposit.inputToken,
|
|
469
|
+
deposit.originChainId,
|
|
470
|
+
deposit.quoteBlockNumber
|
|
471
|
+
);
|
|
472
|
+
return this.hubPoolClient.l2TokenEnabledForL1TokenAtBlock(
|
|
473
|
+
l1Token,
|
|
474
|
+
deposit.destinationChainId,
|
|
475
|
+
deposit.quoteBlockNumber
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
453
480
|
/**
|
|
454
481
|
* A wrapper over the `_update` method that handles errors and logs. This method additionally calls into the
|
|
455
482
|
* HubPoolClient to update the state of this client with data from the HubPool contract.
|
|
@@ -709,8 +736,19 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
|
|
|
709
736
|
* @returns The destination token.
|
|
710
737
|
*/
|
|
711
738
|
protected getDestinationTokenForDeposit(deposit: DepositWithBlock): string {
|
|
712
|
-
|
|
713
|
-
|
|
739
|
+
if (!this.canResolveZeroAddressOutputToken(deposit)) {
|
|
740
|
+
return ZERO_ADDRESS;
|
|
741
|
+
}
|
|
742
|
+
// L1 token should be resolved if we get here:
|
|
743
|
+
const l1Token = this.hubPoolClient!.getL1TokenForL2TokenAtBlock(
|
|
744
|
+
deposit.inputToken,
|
|
745
|
+
deposit.originChainId,
|
|
746
|
+
deposit.quoteBlockNumber
|
|
747
|
+
)!;
|
|
748
|
+
return (
|
|
749
|
+
this.hubPoolClient!.getL2TokenForL1TokenAtBlock(l1Token, deposit.destinationChainId, deposit.quoteBlockNumber) ??
|
|
750
|
+
ZERO_ADDRESS
|
|
751
|
+
);
|
|
714
752
|
}
|
|
715
753
|
|
|
716
754
|
/**
|
|
@@ -100,6 +100,22 @@ export class MockHubPoolClient extends HubPoolClient {
|
|
|
100
100
|
this.spokePoolTokens[l1Token][chainId] = l2Token;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
l2TokenEnabledForL1TokenAtBlock(l1Token: string, destinationChainId: number, hubBlockNumber: number): boolean {
|
|
104
|
+
if (this.spokePoolTokens[l1Token]?.[destinationChainId]) {
|
|
105
|
+
return true;
|
|
106
|
+
} else {
|
|
107
|
+
return super.l2TokenEnabledForL1TokenAtBlock(l1Token, destinationChainId, hubBlockNumber);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
l2TokenHasPoolRebalanceRoute(l2Token: string, chainId: number, hubPoolBlock: number): boolean {
|
|
111
|
+
const l1Token = Object.keys(this.spokePoolTokens).find(
|
|
112
|
+
(l1Token) => this.spokePoolTokens[l1Token]?.[chainId] === l2Token
|
|
113
|
+
);
|
|
114
|
+
if (!l1Token) {
|
|
115
|
+
return super.l2TokenHasPoolRebalanceRoute(l2Token, chainId, hubPoolBlock);
|
|
116
|
+
} else return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
103
119
|
deleteTokenMapping(l1Token: string, chainId: number) {
|
|
104
120
|
delete this.spokePoolTokens[l1Token]?.[chainId];
|
|
105
121
|
}
|
package/src/svm/eventsClient.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { getDeployedAddress, SvmSpokeIdl } from "@across-protocol/contracts";
|
|
2
2
|
import { getSolanaChainId } from "@across-protocol/contracts/dist/src/svm/web3-v1";
|
|
3
|
-
import { BorshEventCoder, utils } from "@coral-xyz/anchor";
|
|
4
3
|
import web3, {
|
|
5
4
|
Address,
|
|
6
5
|
Commitment,
|
|
@@ -9,8 +8,9 @@ import web3, {
|
|
|
9
8
|
RpcTransport,
|
|
10
9
|
Signature,
|
|
11
10
|
} from "@solana/kit";
|
|
11
|
+
import { bs58 } from "../utils";
|
|
12
12
|
import { EventData, EventName, EventWithData } from "./types";
|
|
13
|
-
import {
|
|
13
|
+
import { decodeEvent } from "./utils/events";
|
|
14
14
|
import { isDevnet } from "./utils/helpers";
|
|
15
15
|
|
|
16
16
|
// Utility type to extract the return type for the JSON encoding overload. We only care about the overload where the
|
|
@@ -185,17 +185,11 @@ export class SvmSpokeEventsClient {
|
|
|
185
185
|
this.svmSpokeAddress === ixProgramId &&
|
|
186
186
|
this.svmSpokeEventAuthority === singleIxAccount
|
|
187
187
|
) {
|
|
188
|
-
const ixData =
|
|
188
|
+
const ixData = bs58.decode(ix.data);
|
|
189
189
|
// Skip the first 8 bytes (assumed header) and encode the rest.
|
|
190
|
-
const eventData =
|
|
191
|
-
const
|
|
192
|
-
|
|
193
|
-
const name = getEventName(event.name);
|
|
194
|
-
events.push({
|
|
195
|
-
program: this.svmSpokeAddress,
|
|
196
|
-
data: parseEventData(event?.data),
|
|
197
|
-
name,
|
|
198
|
-
});
|
|
190
|
+
const eventData = Buffer.from(ixData.slice(8)).toString("base64");
|
|
191
|
+
const { name, data } = decodeEvent(SvmSpokeIdl, eventData);
|
|
192
|
+
events.push({ program: this.svmSpokeAddress, name, data });
|
|
199
193
|
}
|
|
200
194
|
}
|
|
201
195
|
}
|
package/src/svm/index.ts
CHANGED
package/src/svm/utils/events.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { BN } from "@coral-xyz/anchor";
|
|
2
|
-
import
|
|
3
|
-
import { EventName, SVMEventNames } from "../types";
|
|
1
|
+
import { BN, BorshEventCoder, Idl } from "@coral-xyz/anchor";
|
|
2
|
+
import { address } from "@solana/kit";
|
|
3
|
+
import { EventName, EventData, SVMEventNames } from "../types";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Parses event data from a transaction.
|
|
@@ -15,7 +15,7 @@ export function parseEventData(eventData: any): any {
|
|
|
15
15
|
|
|
16
16
|
if (typeof eventData === "object") {
|
|
17
17
|
if (eventData.constructor.name === "PublicKey") {
|
|
18
|
-
return
|
|
18
|
+
return address(eventData.toString());
|
|
19
19
|
}
|
|
20
20
|
if (BN.isBN(eventData)) {
|
|
21
21
|
return BigInt(eventData.toString());
|
|
@@ -30,6 +30,18 @@ export function parseEventData(eventData: any): any {
|
|
|
30
30
|
return eventData;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Decodes a raw event according to a supplied IDL.
|
|
35
|
+
*/
|
|
36
|
+
export function decodeEvent(idl: Idl, rawEvent: string): { data: EventData; name: EventName } {
|
|
37
|
+
const event = new BorshEventCoder(idl).decode(rawEvent);
|
|
38
|
+
if (!event) throw new Error(`Malformed rawEvent for IDL ${idl.address}: ${rawEvent}`);
|
|
39
|
+
return {
|
|
40
|
+
name: getEventName(event.name),
|
|
41
|
+
data: parseEventData(event.data),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
33
45
|
/**
|
|
34
46
|
* Converts a snake_case string to camelCase.
|
|
35
47
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./events";
|
|
@@ -2,7 +2,7 @@ import assert from "assert";
|
|
|
2
2
|
import { SpokePoolClient } from "../clients";
|
|
3
3
|
import { DEFAULT_CACHING_TTL, EMPTY_MESSAGE, UNDEFINED_MESSAGE_HASH, ZERO_BYTES } from "../constants";
|
|
4
4
|
import { CachingMechanismInterface, Deposit, DepositWithBlock, Fill, RelayData, SlowFillRequest } from "../interfaces";
|
|
5
|
-
import { getMessageHash, isUnsafeDepositId } from "./SpokeUtils";
|
|
5
|
+
import { getMessageHash, isUnsafeDepositId, isZeroAddress } from "./SpokeUtils";
|
|
6
6
|
import { getNetworkName } from "./NetworkUtils";
|
|
7
7
|
import { bnZero } from "./BigNumberUtils";
|
|
8
8
|
import { getDepositInCache, getDepositKey, setDepositInCache } from "./CachingUtils";
|
|
@@ -208,6 +208,11 @@ export function isZeroValueDeposit(deposit: Pick<Deposit, "inputAmount" | "messa
|
|
|
208
208
|
return deposit.inputAmount.eq(0) && isMessageEmpty(deposit.message);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
+
export function invalidOutputToken(deposit: Pick<DepositWithBlock, "outputToken">): boolean {
|
|
212
|
+
// If the output token is zero address, then it is invalid.
|
|
213
|
+
return isZeroAddress(deposit.outputToken);
|
|
214
|
+
}
|
|
215
|
+
|
|
211
216
|
export function isZeroValueFillOrSlowFillRequest(
|
|
212
217
|
e: Pick<Fill | SlowFillRequest, "inputAmount" | "messageHash">
|
|
213
218
|
): boolean {
|
package/src/utils/common.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Decimal from "decimal.js";
|
|
2
|
+
import bs58 from "bs58";
|
|
2
3
|
import { ethers } from "ethers";
|
|
3
4
|
import { BigNumber, BigNumberish, BN, formatUnits, parseUnits, toBN } from "./BigNumberUtils";
|
|
4
5
|
import { ConvertDecimals } from "./FormattingUtils";
|
|
@@ -8,6 +9,7 @@ export const AddressZero = ethers.constants.AddressZero;
|
|
|
8
9
|
export const MAX_BIG_INT = BigNumber.from(Number.MAX_SAFE_INTEGER.toString());
|
|
9
10
|
|
|
10
11
|
export const { keccak256 } = ethers.utils;
|
|
12
|
+
export { bs58 };
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* toBNWei.
|