Skip to content
Open
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@across-protocol/sdk",
"author": "UMA Team",
"version": "4.3.37",
"version": "4.3.38",
"license": "AGPL-3.0",
"homepage": "https://docs.across.to/reference/sdk",
"files": [
Expand Down
9 changes: 5 additions & 4 deletions src/arch/evm/SpokeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FillStatus,
FillWithBlock,
RelayData,
RelayDataWithMessageHash,
RelayExecutionEventInfo,
SpeedUpCommon,
} from "../../interfaces";
Expand Down Expand Up @@ -190,7 +191,7 @@ export async function findDepositBlock(
*/
export async function relayFillStatus(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
blockTag: BlockTag = "latest",
destinationChainId?: number
): Promise<FillStatus> {
Expand All @@ -213,7 +214,7 @@ export async function relayFillStatus(

export async function fillStatusArray(
spokePool: Contract,
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
blockTag: BlockTag = "latest"
): Promise<(FillStatus | undefined)[]> {
const fillStatuses = "fillStatuses";
Expand Down Expand Up @@ -258,7 +259,7 @@ export async function fillStatusArray(
*/
export async function findFillBlock(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
lowBlockNumber: number,
highBlockNumber?: number
): Promise<number | undefined> {
Expand Down Expand Up @@ -313,7 +314,7 @@ export async function findFillBlock(

export async function findFillEvent(
spokePool: Contract,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
lowBlockNumber: number,
highBlockNumber?: number
): Promise<FillWithBlock | undefined> {
Expand Down
31 changes: 20 additions & 11 deletions src/arch/svm/SpokeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MessageTransmitterClient, SvmSpokeClient, TokenMessengerMinterClient } from "@across-protocol/contracts";
import { decodeFillStatusAccount, fetchState } from "@across-protocol/contracts/dist/src/svm/clients/SvmSpoke";
import { decodeMessageHeader, hashNonEmptyMessage } from "@across-protocol/contracts/dist/src/svm/web3-v1";
import { decodeMessageHeader } from "@across-protocol/contracts/dist/src/svm/web3-v1";
import { intToU8Array32 } from "@across-protocol/contracts/dist/src/svm/web3-v1/conversionUtils";
import { SYSTEM_PROGRAM_ADDRESS } from "@solana-program/system";
import {
Expand Down Expand Up @@ -37,7 +37,14 @@ import assert from "assert";
import { arrayify, hexZeroPad, hexlify } from "ethers/lib/utils";
import { Logger } from "winston";
import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../../constants";
import { DepositWithBlock, FillStatus, FillWithBlock, RelayData, RelayExecutionEventInfo } from "../../interfaces";
import {
DepositWithBlock,
FillStatus,
FillWithBlock,
RelayData,
RelayDataWithMessageHash,
RelayExecutionEventInfo,
} from "../../interfaces";
import {
BigNumber,
EvmAddress,
Expand Down Expand Up @@ -83,7 +90,7 @@ import {
*/
export const SLOT_DURATION_MS = 400;

type ProtoFill = Omit<RelayData, "recipient" | "outputToken"> & {
type ProtoFill = Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand Down Expand Up @@ -261,7 +268,7 @@ export async function findDeposit(
*/
export async function relayFillStatus(
programId: Address,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
atHeight?: number
Expand Down Expand Up @@ -311,7 +318,7 @@ export async function relayFillStatus(
*/
export async function fillStatusArray(
programId: Address,
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
atHeight?: number,
Expand Down Expand Up @@ -394,7 +401,7 @@ export async function fillStatusArray(
* @returns The fill event with block info, or `undefined` if not found.
*/
export async function findFillEvent(
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number,
svmEventsClient: SvmCpiEventsClient,
fromSlot: number,
Expand Down Expand Up @@ -566,7 +573,7 @@ export function createTokenAccountsInstruction(
export async function getFillRelayTx(
spokePoolAddr: SvmAddress,
solanaClient: SVMProvider,
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand All @@ -583,6 +590,7 @@ export async function getFillRelayTx(
);

const program = toAddress(spokePoolAddr);

const _relayDataHash = getRelayDataHash(relayData, destinationChainId);
const relayDataHash = new Uint8Array(Buffer.from(_relayDataHash.slice(2), "hex"));

Expand Down Expand Up @@ -770,7 +778,7 @@ export const createRequestSlowFillInstruction = async (
export async function getSlowFillRequestTx(
spokePoolAddr: SvmAddress,
solanaClient: SVMProvider,
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand All @@ -792,6 +800,7 @@ export async function getSlowFillRequestTx(
} = relayData;

const program = toAddress(spokePoolAddr);

const relayDataHash = getRelayDataHash(relayData, destinationChainId);

const [state, fillStatus, eventAuthority] = await Promise.all([
Expand Down Expand Up @@ -881,12 +890,12 @@ export async function getAssociatedTokenAddress(
return associatedToken;
}

export function getRelayDataHash(relayData: RelayData, destinationChainId: number): string {
export function getRelayDataHash(relayData: RelayDataWithMessageHash, destinationChainId: number): string {
const addressEncoder = getAddressEncoder();
const uint64Encoder = getU64Encoder();
const uint32Encoder = getU32Encoder();

assert(relayData.message.startsWith("0x"), "Message must be a hex string");
assert(relayData.messageHash.startsWith("0x"), "Message hash must be a hex string");
const encodeAddress = (data: SdkAddress) => Uint8Array.from(addressEncoder.encode(toAddress(data)));

const contentToHash = Buffer.concat([
Expand All @@ -901,7 +910,7 @@ export function getRelayDataHash(relayData: RelayData, destinationChainId: numbe
arrayify(hexZeroPad(hexlify(relayData.depositId), 32)),
Uint8Array.from(uint32Encoder.encode(relayData.fillDeadline)),
Uint8Array.from(uint32Encoder.encode(relayData.exclusivityDeadline)),
hashNonEmptyMessage(Buffer.from(arrayify(relayData.message))),
Uint8Array.from(Buffer.from(relayData.messageHash.slice(2), "hex")),
Uint8Array.from(uint64Encoder.encode(BigInt(destinationChainId))),
]);
return keccak256(contentToHash);
Expand Down
4 changes: 2 additions & 2 deletions src/arch/svm/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
import assert from "assert";
import bs58 from "bs58";
import { ethers } from "ethers";
import { FillType, RelayData } from "../../interfaces";
import { FillType, RelayDataWithMessageHash } from "../../interfaces";
import { BigNumber, Address as SdkAddress, biMin, getRelayDataHash, isDefined, isUint8Array } from "../../utils";
import { getTimestampForSlot } from "./SpokeUtils";
import { AttestedCCTPMessage, EventName, SVMEventNames, SVMProvider } from "./types";
Expand Down Expand Up @@ -264,7 +264,7 @@ export async function getStatePda(programId: Address): Promise<Address> {
*/
export async function getFillStatusPda(
programId: Address,
relayData: RelayData,
relayData: RelayDataWithMessageHash,
destinationChainId: number
): Promise<Address> {
const relayDataHash = getRelayDataHash(relayData, destinationChainId);
Expand Down
9 changes: 6 additions & 3 deletions src/clients/SpokePoolClient/EVMSpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
relayFillStatus,
getTimestampForBlock as _getTimestampForBlock,
} from "../../arch/evm";
import { DepositWithBlock, FillStatus, RelayData } from "../../interfaces";
import { DepositWithBlock, FillStatus, RelayDataWithMessageHash } from "../../interfaces";
import {
BigNumber,
DepositSearchResult,
Expand Down Expand Up @@ -48,11 +48,14 @@ export class EVMSpokePoolClient extends SpokePoolClient {
this.spokePoolAddress = EvmAddress.from(spokePool.address);
}

public override relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus> {
public override relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus> {
return relayFillStatus(this.spokePool, relayData, atHeight, this.chainId);
}

public override fillStatusArray(relayData: RelayData[], atHeight?: number): Promise<(FillStatus | undefined)[]> {
public override fillStatusArray(
relayData: RelayDataWithMessageHash[],
atHeight?: number
): Promise<(FillStatus | undefined)[]> {
return fillStatusArray(this.spokePool, relayData, atHeight);
}

Expand Down
6 changes: 3 additions & 3 deletions src/clients/SpokePoolClient/SVMSpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
relayFillStatus,
fillStatusArray,
} from "../../arch/svm";
import { FillStatus, RelayData, SortableEvent } from "../../interfaces";
import { FillStatus, RelayDataWithMessageHash, SortableEvent } from "../../interfaces";
import {
BigNumber,
DepositSearchResult,
Expand Down Expand Up @@ -243,7 +243,7 @@ export class SVMSpokePoolClient extends SpokePoolClient {
/**
* Retrieves the fill status for a given relay data from the SVM chain.
*/
public override relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus> {
public override relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus> {
return relayFillStatus(this.programId, relayData, this.chainId, this.svmEventsClient, atHeight);
}

Expand All @@ -254,7 +254,7 @@ export class SVMSpokePoolClient extends SpokePoolClient {
* @returns The fill status for each of the given relay data.
*/
public fillStatusArray(
relayData: RelayData[],
relayData: RelayDataWithMessageHash[],
atHeight?: number,
destinationChainId?: number
): Promise<(FillStatus | undefined)[]> {
Expand Down
8 changes: 6 additions & 2 deletions src/clients/SpokePoolClient/SpokePoolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
SpeedUpWithBlock,
TokensBridged,
RelayExecutionEventInfo,
RelayDataWithMessageHash,
} from "../../interfaces";
import { BaseAbstractClient, UpdateFailureReason } from "../BaseAbstractClient";
import { AcrossConfigStoreClient } from "../AcrossConfigStoreClient";
Expand Down Expand Up @@ -980,13 +981,16 @@ export abstract class SpokePoolClient extends BaseAbstractClient {
* @param atHeight The height at which to query the fill status.
* @returns The fill status for the given relay data.
*/
public abstract relayFillStatus(relayData: RelayData, atHeight?: number): Promise<FillStatus>;
public abstract relayFillStatus(relayData: RelayDataWithMessageHash, atHeight?: number): Promise<FillStatus>;

/**
* Retrieves the fill status for an array of given relay data.
* @param relayData The array relay data to retrieve the fill status for.
* @param atHeight The height at which to query the fill status.
* @returns The fill status for each of the given relay data.
*/
public abstract fillStatusArray(relayData: RelayData[], atHeight?: number): Promise<(FillStatus | undefined)[]>;
public abstract fillStatusArray(
relayData: RelayDataWithMessageHash[],
atHeight?: number
): Promise<(FillStatus | undefined)[]>;
}
4 changes: 4 additions & 0 deletions src/interfaces/SpokePool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { SpokePoolClient } from "../clients";
import { BigNumber, Address, EvmAddress } from "../utils";
import { RelayerRefundLeaf } from "./HubPool";

export interface RelayDataWithMessageHash extends RelayData {
messageHash: string;
}

export interface RelayData {
originChainId: number;
depositor: Address;
Expand Down
6 changes: 3 additions & 3 deletions src/relayFeeCalculator/chain-queries/baseQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { isL2Provider as isOptimismL2Provider } from "@eth-optimism/sdk/dist/l2-
import { PopulatedTransaction, providers, VoidSigner } from "ethers";
import { Coingecko } from "../../coingecko";
import { CHAIN_IDs } from "../../constants";
import { RelayData } from "../../interfaces";
import { RelayData, RelayDataWithMessageHash } from "../../interfaces";
import { SpokePool, SpokePool__factory } from "../../typechain";
import { populateV3Relay } from "../../arch/evm";
import {
Expand Down Expand Up @@ -72,7 +72,7 @@ export class QueryBase implements QueryInterface {
* @returns The gas estimate for this function call (multiplied with the optional buffer).
*/
async getGasCosts(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId),
options: Partial<{
gasPrice: BigNumberish;
Expand Down Expand Up @@ -144,7 +144,7 @@ export class QueryBase implements QueryInterface {
* @returns Estimated gas cost based on ethers.VoidSigner's gas estimation
*/
async getNativeGasCost(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId)
): Promise<BigNumber> {
const { recipient, outputToken, exclusiveRelayer } = relayData;
Expand Down
8 changes: 4 additions & 4 deletions src/relayFeeCalculator/chain-queries/svmQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { SVMProvider, SolanaVoidSigner, getFillRelayTx } from "../../arch/svm";
import { Coingecko } from "../../coingecko";
import { CHAIN_IDs } from "../../constants";
import { getGasPriceEstimate } from "../../gasPriceOracle";
import { RelayData } from "../../interfaces";
import { RelayDataWithMessageHash } from "../../interfaces";
import { Address, BigNumber, BigNumberish, SvmAddress, TransactionCostEstimate, toBN } from "../../utils";
import { Logger, QueryInterface, getDefaultRelayer } from "../relayFeeCalculator";
import { SymbolMappingType } from "./";
Expand Down Expand Up @@ -53,7 +53,7 @@ export class SvmQuery implements QueryInterface {
* @returns The gas estimate for this function call (multiplied with the optional buffer).
*/
async getGasCosts(
relayData: RelayData & { destinationChainId: number },
relayData: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(relayData.destinationChainId),
options: Partial<{
gasPrice: BigNumberish;
Expand Down Expand Up @@ -105,7 +105,7 @@ export class SvmQuery implements QueryInterface {
* @returns Estimated gas cost in compute units
*/
async getNativeGasCost(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer = getDefaultRelayer(deposit.destinationChainId)
): Promise<BigNumber> {
const { destinationChainId, recipient, outputToken, exclusiveRelayer } = deposit;
Expand All @@ -131,7 +131,7 @@ export class SvmQuery implements QueryInterface {
* @returns FillRelay transaction
*/
protected async getFillRelayTx(
relayData: Omit<RelayData, "recipient" | "outputToken"> & {
relayData: Omit<RelayDataWithMessageHash, "recipient" | "outputToken"> & {
destinationChainId: number;
recipient: SvmAddress;
outputToken: SvmAddress;
Expand Down
13 changes: 8 additions & 5 deletions src/relayFeeCalculator/relayFeeCalculator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
DEFAULT_SIMULATED_RELAYER_ADDRESS_SVM,
TOKEN_SYMBOLS_MAP,
} from "../constants";
import { RelayData } from "../interfaces";
import { RelayDataWithMessageHash } from "../interfaces";
import {
BigNumber,
BigNumberish,
Expand Down Expand Up @@ -33,7 +33,7 @@ import {
// This needs to be implemented for every chain and passed into RelayFeeCalculator
export interface QueryInterface {
getGasCosts: (
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer: Address,
options?: Partial<{
gasPrice: BigNumberish;
Expand All @@ -45,7 +45,10 @@ export interface QueryInterface {
}>
) => Promise<TransactionCostEstimate>;
getTokenPrice: (tokenSymbol: string) => Promise<number>;
getNativeGasCost: (deposit: RelayData & { destinationChainId: number }, relayer: Address) => Promise<BigNumber>;
getNativeGasCost: (
deposit: RelayDataWithMessageHash & { destinationChainId: number },
relayer: Address
) => Promise<BigNumber>;
}

export const expectedCapitalCostsKeys = ["lowerBound", "upperBound", "cutoff", "decimals"];
Expand Down Expand Up @@ -254,7 +257,7 @@ export class RelayFeeCalculator {
* the correct parameters to see a full fill.
*/
async gasFeePercent(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
outputAmount: BigNumberish,
simulateZeroFill = false,
relayerAddress = getDefaultRelayer(deposit.destinationChainId),
Expand Down Expand Up @@ -493,7 +496,7 @@ export class RelayFeeCalculator {
* @returns A resulting `RelayerFeeDetails` object
*/
async relayerFeeDetails(
deposit: RelayData & { destinationChainId: number },
deposit: RelayDataWithMessageHash & { destinationChainId: number },
outputAmount?: BigNumberish,
simulateZeroFill = false,
relayerAddress = getDefaultRelayer(deposit.destinationChainId),
Expand Down
Loading