Skip to content
This repository was archived by the owner on Jun 16, 2025. It is now read-only.

Commit a1d0c43

Browse files
committed
replace fast market order transaction creation and submission with protocol
1 parent 77e0745 commit a1d0c43

File tree

4 files changed

+105
-120
lines changed

4 files changed

+105
-120
lines changed

evm/ts/src/TokenRouter/index.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { deserialize, CircleBridge, VAA } from "@wormhole-foundation/sdk-definitions";
12
import { LiquidityLayerTransactionResult, PreparedInstruction } from "..";
3+
import { encoding } from "@wormhole-foundation/sdk-base";
24
export * from "./evm";
35

46
export type FastTransferParameters = {
@@ -14,6 +16,21 @@ export type OrderResponse = {
1416
circleAttestation: Buffer | Uint8Array;
1517
};
1618

19+
export type DecodedOrderResponse = {
20+
vaa: VAA<"FastTransfer:CctpDeposit">;
21+
cctp: CircleBridge.Attestation;
22+
};
23+
export function decodedOrderResponse(response: OrderResponse): DecodedOrderResponse {
24+
const [msg] = CircleBridge.deserialize(response.circleBridgeMessage);
25+
return {
26+
vaa: deserialize("FastTransfer:CctpDeposit", response.encodedWormholeMessage),
27+
cctp: {
28+
message: msg,
29+
attestation: encoding.hex.encode(response.circleAttestation),
30+
},
31+
};
32+
}
33+
1734
export type Endpoint = {
1835
router: string | Buffer | Uint8Array;
1936
mintRecipient: string | Buffer | Uint8Array;

evm/ts/src/protocol/tokenRouter.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,28 @@ export class EvmTokenRouter<N extends Network, C extends EvmChains>
4949
yield this.createUnsignedTx({ ...txReq, from }, "TokenRouter.placeMarketOrder");
5050
}
5151

52+
async *placeFastMarketOrder(sender: AnyEvmAddress, order: TokenRouter.OrderRequest) {
53+
const from = new EvmAddress(sender).unwrap();
54+
const msg = order.redeemerMessage ? order.redeemerMessage : new Uint8Array();
55+
56+
const refundAddress = order.refundAddress
57+
? new EvmAddress(order.refundAddress).unwrap()
58+
: undefined;
59+
60+
const txReq = await this.placeFastMarketOrderTx(
61+
order.amountIn,
62+
toChainId(order.targetChain),
63+
order.redeemer.toUint8Array(),
64+
msg,
65+
order.maxFee!,
66+
order.deadline!,
67+
order.minAmountOut,
68+
refundAddress,
69+
);
70+
71+
yield this.createUnsignedTx({ ...txReq, from }, "TokenRouter.placeMarketOrder");
72+
}
73+
5274
async *redeemFill(
5375
sender: AnyEvmAddress,
5476
vaa: VAA<"FastTransfer:CctpDeposit">,

evm/ts/src/testing/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Chain, Network } from "@wormhole-foundation/sdk-base";
88
import {
99
SignAndSendSigner,
1010
UnsignedTransaction,
11+
toNative,
1112
toUniversal,
1213
} from "@wormhole-foundation/sdk-definitions";
1314
import { EvmChains, EvmNativeSigner } from "@wormhole-foundation/sdk-evm";

evm/ts/tests/04__fastMarketOrder.ts

Lines changed: 65 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ import { expect } from "chai";
22
import { ethers } from "ethers";
33
import {
44
EvmMatchingEngine,
5+
EvmTokenRouter,
56
MessageDecoder,
67
OrderResponse,
8+
decodedOrderResponse,
79
errorDecoder,
8-
EvmTokenRouter,
910
} from "../src";
1011
import {
1112
CircleAttester,
@@ -17,30 +18,25 @@ import {
1718
ValidNetwork,
1819
WALLET_PRIVATE_KEYS,
1920
burnAllUsdc,
21+
getSdkSigner,
2022
mine,
2123
mineToGracePeriod,
2224
mineToPenaltyPeriod,
2325
mineWait,
2426
mintNativeUsdc,
2527
nonceManagedWallet,
2628
parseLiquidityLayerEnvFile,
27-
tryNativeToUint8Array,
29+
signSendMineWait,
2830
sleep,
2931
toContractAddresses,
30-
signSendMineWait,
31-
getSdkSigner,
32+
tryNativeToUint8Array,
3233
} from "../src/testing";
3334
import { IERC20__factory } from "../src/types";
3435

35-
import { toChainId } from "@wormhole-foundation/sdk-base";
36-
import {
37-
deserialize,
38-
keccak256,
39-
toNative,
40-
toUniversal,
41-
} from "@wormhole-foundation/sdk-definitions";
42-
import "@wormhole-foundation/sdk-evm";
4336
import { TokenRouter } from "@wormhole-foundation/example-liquidity-layer-definitions";
37+
import { encoding, toChainId } from "@wormhole-foundation/sdk-base";
38+
import { deserialize, keccak256, toUniversal } from "@wormhole-foundation/sdk-definitions";
39+
import "@wormhole-foundation/sdk-evm";
4440

4541
// Cannot send a fast market order from the matching engine chain.
4642
const CHAIN_PATHWAYS: ValidNetwork[][] = [
@@ -165,32 +161,25 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
165161
})();
166162
localVariables.set("amountIn", amountIn);
167163

168-
const targetChain = toChainId(toChainName);
169164
const minAmountOut = BigInt(0);
170165
const deadline = 0;
166+
const order: TokenRouter.OrderRequest = {
167+
amountIn,
168+
minAmountOut,
169+
deadline,
170+
maxFee: FEE_AMOUNT,
171+
targetChain: toChainName,
172+
redeemer: toUniversal(toChainName, toWallet.address),
173+
redeemerMessage: encoding.bytes.encode("All your base are belong to us."),
174+
refundAddress: toUniversal(fromChainName, fromWallet.address),
175+
};
171176

172-
const receipt = await fromTokenRouter
173-
.placeFastMarketOrderTx(
174-
amountIn,
175-
targetChain,
176-
Buffer.from(tryNativeToUint8Array(toWallet.address, toChainName)),
177-
Buffer.from("All your base are belong to us."),
178-
FEE_AMOUNT,
179-
deadline,
180-
minAmountOut,
181-
fromWallet.address,
182-
)
183-
.then((txReq) => fromWallet.sendTransaction(txReq))
184-
.then((tx) => mineWait(fromProvider, tx))
185-
.catch((err) => {
186-
console.log(err);
187-
console.log(errorDecoder(err));
188-
throw err;
189-
});
190-
177+
const txs = fromTokenRouter.placeFastMarketOrder(fromWallet.address, order);
178+
const receipt = await signSendMineWait(txs, fromSigner);
191179
const transactionResult = await fromTokenRouter.getTransactionResults(
192180
receipt!.hash,
193181
);
182+
194183
expect(transactionResult.wormhole.emitterAddress).to.eql(
195184
tryNativeToUint8Array(fromEnv.tokenRouterAddress, fromChainName),
196185
);
@@ -474,15 +463,9 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
474463
const usdc = IERC20__factory.connect(toEnv.tokenAddress, toProvider);
475464
const balanceBefore = await usdc.balanceOf(toWallet.address);
476465

477-
const receipt = await toTokenRouter
478-
.redeemFillTx(orderResponse)
479-
.then((txReq) => toWallet.sendTransaction(txReq))
480-
.then((tx) => mineWait(toProvider, tx))
481-
.catch((err) => {
482-
console.log(err);
483-
console.log(errorDecoder(err));
484-
throw err;
485-
});
466+
const { vaa, cctp } = decodedOrderResponse(orderResponse);
467+
const txs = toTokenRouter.redeemFill(toWallet.address, vaa, cctp);
468+
const receipt = await signSendMineWait(txs, toSigner);
486469

487470
// Validate balance changes.
488471
const { bidPrice, amount } = await engine.liveAuctionInfo(auctionId);
@@ -568,27 +551,22 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
568551
})();
569552
localVariables.set("amountIn", amountIn);
570553

571-
const targetChain = toChainId(toChainName);
572554
const minAmountOut = BigInt(0);
573555
const deadline = 0;
574-
const receipt = await fromTokenRouter
575-
.placeFastMarketOrderTx(
576-
amountIn,
577-
targetChain,
578-
Buffer.from(tryNativeToUint8Array(toWallet.address, toChainName)),
579-
Buffer.from("All your base are belong to us."),
580-
FEE_AMOUNT,
581-
deadline,
582-
minAmountOut,
583-
fromWallet.address,
584-
)
585-
.then((txReq) => fromWallet.sendTransaction(txReq))
586-
.then((tx) => mineWait(fromProvider, tx))
587-
.catch((err) => {
588-
console.log(err);
589-
console.log(errorDecoder(err));
590-
throw err;
591-
});
556+
557+
const order: TokenRouter.OrderRequest = {
558+
amountIn,
559+
minAmountOut,
560+
deadline,
561+
maxFee: FEE_AMOUNT,
562+
targetChain: toChainName,
563+
redeemer: toUniversal(toChainName, toWallet.address),
564+
redeemerMessage: encoding.bytes.encode("All your base are belong to us."),
565+
refundAddress: toUniversal(fromChainName, fromWallet.address),
566+
};
567+
568+
const txs = fromTokenRouter.placeFastMarketOrder(fromWallet.address, order);
569+
const receipt = await signSendMineWait(txs, fromSigner);
592570
const transactionResult = await fromTokenRouter.getTransactionResults(
593571
receipt!.hash,
594572
);
@@ -894,15 +872,9 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
894872
const usdc = IERC20__factory.connect(toEnv.tokenAddress, toProvider);
895873
const balanceBefore = await usdc.balanceOf(toWallet.address);
896874

897-
const receipt = await toTokenRouter
898-
.redeemFillTx(orderResponse)
899-
.then((txReq) => toWallet.sendTransaction(txReq))
900-
.then((tx) => mineWait(toProvider, tx))
901-
.catch((err) => {
902-
console.log(err);
903-
console.log(errorDecoder(err));
904-
throw err;
905-
});
875+
const { vaa, cctp } = decodedOrderResponse(orderResponse);
876+
const txs = toTokenRouter.redeemFill(toWallet.address, vaa, cctp);
877+
const receipt = await signSendMineWait(txs, toSigner);
906878

907879
// Validate balance changes.
908880
const [bidPrice, amount] = await engine
@@ -991,24 +963,19 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
991963
const targetChain = toChainId(toChainName);
992964
const minAmountOut = BigInt(0);
993965
const deadline = 0;
994-
const receipt = await fromTokenRouter
995-
.placeFastMarketOrderTx(
996-
amountIn,
997-
targetChain,
998-
Buffer.from(tryNativeToUint8Array(toWallet.address, toChainName)),
999-
Buffer.from("All your base are belong to us."),
1000-
FEE_AMOUNT,
1001-
deadline,
1002-
minAmountOut,
1003-
fromWallet.address,
1004-
)
1005-
.then((txReq) => fromWallet.sendTransaction(txReq))
1006-
.then((tx) => mineWait(fromProvider, tx))
1007-
.catch((err) => {
1008-
console.log(err);
1009-
console.log(errorDecoder(err));
1010-
throw err;
1011-
});
966+
967+
const order: TokenRouter.OrderRequest = {
968+
amountIn,
969+
minAmountOut,
970+
deadline,
971+
maxFee: FEE_AMOUNT,
972+
targetChain: toChainName,
973+
redeemer: toUniversal(toChainName, toWallet.address),
974+
redeemerMessage: encoding.bytes.encode("All your base are belong to us."),
975+
refundAddress: toUniversal(fromChainName, fromWallet.address),
976+
};
977+
const txs = fromTokenRouter.placeFastMarketOrder(fromWallet.address, order);
978+
const receipt = await signSendMineWait(txs, fromSigner);
1012979
const transactionResult = await fromTokenRouter.getTransactionResults(
1013980
receipt!.hash,
1014981
);
@@ -1141,15 +1108,9 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
11411108
const usdc = IERC20__factory.connect(toEnv.tokenAddress, toProvider);
11421109
const balanceBefore = await usdc.balanceOf(toWallet.address);
11431110

1144-
const receipt = await toTokenRouter
1145-
.redeemFillTx(orderResponse)
1146-
.then((txReq) => toWallet.sendTransaction(txReq))
1147-
.then((tx) => mineWait(toProvider, tx))
1148-
.catch((err) => {
1149-
console.log(err);
1150-
console.log(errorDecoder(err));
1151-
throw err;
1152-
});
1111+
const { vaa, cctp } = decodedOrderResponse(orderResponse);
1112+
const txs = toTokenRouter.redeemFill(toWallet.address, vaa, cctp);
1113+
const receipt = await signSendMineWait(txs, toSigner);
11531114

11541115
// Validate balance changes.
11551116
const balanceAfter = await usdc.balanceOf(toWallet.address);
@@ -1199,41 +1160,25 @@ describe("Fast Market Order Business Logic -- CCTP to CCTP", function (this: Moc
11991160

12001161
localVariables.set("amountIn", amountIn);
12011162

1202-
const targetChain = toChainId(toChainName);
1203-
const minAmountOut = BigInt(0);
1204-
12051163
// Set the deadline to the current block timestamp.
12061164
const currentBlock = await engineProvider.getBlockNumber();
12071165
const deadline = (await engineProvider.getBlock(currentBlock))!.timestamp;
1208-
1209-
const redeemer = toNative(toChainName, toWallet.address).toUniversalAddress();
1166+
const minAmountOut = BigInt(0);
12101167

12111168
const order: TokenRouter.OrderRequest = {
12121169
amountIn,
12131170
minAmountOut,
1214-
redeemer,
1171+
redeemer: toUniversal(toChainName, toWallet.address),
1172+
deadline,
1173+
maxFee: FEE_AMOUNT,
12151174
targetChain: toChainName,
1175+
redeemerMessage: encoding.bytes.encode("All your base are belong to us."),
1176+
refundAddress: toUniversal(fromChainName, fromWallet.address),
12161177
};
12171178

1218-
const txs = fromTokenRouter.placeMarketOrder(fromWallet.address, order);
1179+
const txs = fromTokenRouter.placeFastMarketOrder(fromWallet.address, order);
12191180
const receipt = await signSendMineWait(txs, fromSigner);
1220-
//.placeFastMarketOrderTx(
1221-
// amountIn,
1222-
// targetChain,
1223-
// Buffer.from(),
1224-
// Buffer.from("All your base are belong to us."),
1225-
// FEE_AMOUNT,
1226-
// deadline!,
1227-
// minAmountOut,
1228-
// fromWallet.address,
1229-
// )
1230-
// .then((txReq) => fromWallet.sendTransaction(txReq))
1231-
// .then((tx) => mineWait(fromProvider, tx))
1232-
// .catch((err) => {
1233-
// console.log(err);
1234-
// console.log(errorDecoder(err));
1235-
// throw err;
1236-
// });
1181+
12371182
const transactionResult = await fromTokenRouter.getTransactionResults(
12381183
receipt!.hash,
12391184
);

0 commit comments

Comments
 (0)