Skip to content

Commit 6c46231

Browse files
authored
Feat/allow encoded message (#115)
* allow pre-encoded message * test with simple transfer * add changeset * assert message
1 parent bb73f49 commit 6c46231

File tree

4 files changed

+118
-2
lines changed

4 files changed

+118
-2
lines changed

.changeset/tidy-kings-kick.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@across-protocol/app-sdk": patch
3+
---
4+
5+
Allow passing of pre encoded message field in getQuote

apps/example/lib/stake.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { CrossChainAction } from "@across-protocol/app-sdk";
21
import { Address, encodeFunctionData } from "viem";
32
import { optimism } from "viem/chains";
43

packages/sdk/src/actions/getQuote.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Address, Hex } from "viem";
1+
import { Address, Hex, isHex } from "viem";
22
import { Amount, CrossChainAction } from "../types/index.js";
33
import {
44
getMultiCallHandlerAddress,
@@ -129,6 +129,10 @@ export async function getQuote(params: GetQuoteParams): Promise<Quote> {
129129
let message: Hex = "0x";
130130
let recipient = _recipient;
131131

132+
if (isHex(crossChainMessage)) {
133+
message = crossChainMessage;
134+
}
135+
132136
if (crossChainMessage && typeof crossChainMessage === "object") {
133137
if (crossChainMessage.actions.length === 0) {
134138
throw new Error("No 'crossChainMessage.actions' provided");
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import { assert, assertType, describe, test } from "vitest";
2+
import { testClient } from "../../common/sdk.js";
3+
import {
4+
buildMulticallHandlerMessage,
5+
getMultiCallHandlerAddress,
6+
type Quote,
7+
type Route,
8+
} from "../../../src/index.js";
9+
import { encodeFunctionData, erc20Abi, parseUnits } from "viem";
10+
import { arbitrum, optimism } from "viem/chains";
11+
12+
// arbitrum USDC
13+
const inputToken = {
14+
address: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
15+
symbol: "USDC",
16+
name: "USD Coin",
17+
decimals: 6,
18+
} as const;
19+
20+
// optimism USDC
21+
const outputToken = {
22+
address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",
23+
symbol: "USDC",
24+
name: "USD Coin",
25+
decimals: 6,
26+
} as const;
27+
28+
const testEoa = "0x9A8f92a830A5cB89a3816e3D267CB7791c16b04D";
29+
const inputAmount = 100;
30+
const inputAmountBN = parseUnits(inputAmount.toString(), inputToken.decimals);
31+
const outputAmountBN = inputAmountBN / 2n; // 50% of input ensures this doesn't fail, since we cannot recompute after getting the initial quote
32+
33+
// ARBITRUM => OPTIMISM
34+
const testRoute: Route = {
35+
originChainId: arbitrum.id,
36+
destinationChainId: optimism.id,
37+
inputToken: inputToken.address,
38+
outputToken: outputToken.address,
39+
inputTokenSymbol: inputToken.symbol,
40+
outputTokenSymbol: outputToken.symbol,
41+
isNative: false,
42+
};
43+
44+
describe("getQuote with Raw Pre-Encoded Message", () => {
45+
test("Gets a quote using a raw pre-encoded message from a test EOA", async () => {
46+
// pre compute a simple transfer message
47+
const calldata = buildMulticallHandlerMessage({
48+
fallbackRecipient: testEoa,
49+
actions: [
50+
{
51+
target: outputToken.address,
52+
value: 0n,
53+
callData: encodeFunctionData({
54+
abi: erc20Abi,
55+
functionName: "transfer",
56+
args: [testEoa, outputAmountBN],
57+
}),
58+
},
59+
],
60+
});
61+
62+
// Invoke getQuote with the raw message
63+
const _quote = await testClient.getQuote({
64+
route: testRoute,
65+
recipient: getMultiCallHandlerAddress(testRoute.destinationChainId),
66+
inputAmount: inputAmountBN,
67+
crossChainMessage: calldata,
68+
// Removed 'sender' as it's not a parameter for getQuote
69+
});
70+
71+
// Assert that a quote was returned
72+
assert(_quote, "No quote returned for the provided route and message");
73+
assertType<Quote>(_quote);
74+
75+
assert.equal(
76+
_quote.deposit.message,
77+
calldata,
78+
"Message should be equal to pre-encoded calldata",
79+
);
80+
81+
// Optional: Additional assertions to verify quote details
82+
assert.equal(
83+
_quote.deposit.inputAmount.toString(),
84+
inputAmountBN.toString(),
85+
"Input amounts should match",
86+
);
87+
assert.equal(
88+
_quote.deposit.originChainId,
89+
testRoute.originChainId,
90+
"Origin chain IDs should match",
91+
);
92+
assert.equal(
93+
_quote.deposit.destinationChainId,
94+
testRoute.destinationChainId,
95+
"Destination chain IDs should match",
96+
);
97+
assert.equal(
98+
_quote.deposit.inputToken,
99+
testRoute.inputToken,
100+
"Input tokens should match",
101+
);
102+
assert.equal(
103+
_quote.deposit.outputToken,
104+
testRoute.outputToken,
105+
"Output tokens should match",
106+
);
107+
});
108+
});

0 commit comments

Comments
 (0)