Skip to content

Commit

Permalink
add test
Browse files Browse the repository at this point in the history
  • Loading branch information
AntonAndell committed Oct 23, 2024
1 parent 83b03e0 commit 415fb94
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 80 deletions.
52 changes: 23 additions & 29 deletions sdk/src/evm-intents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ import { PERMIT2_ADDRESS, PermitTransferFrom, SignatureTransfer, Witness } from
import { _TypedDataEncoder } from '@ethersproject/hash'
import { MaxUint256, Interface} from 'ethers';

const arbNID = "nid"
const suiNID = "SUI"

const intentContract = "0xDc4c9866b930a4dBe159263F47B229dcE404F355";
const token = "0xb1D4538B4571d411F07960EF2838Ce337FE1E80E"
const perm2 = PERMIT2_ADDRESS
const amount = BigInt(10)

const toAddress = "SUI"
const toToken = "SUI"
const toAmount = BigInt(10)

const erc20Abi = [
{
"constant": false,
Expand Down Expand Up @@ -47,7 +35,7 @@ const erc20Abi = [



class EVMIntents {
export class EVMIntents{
address: string;
provider: JsonRpcProvider;
intents: Contract;
Expand All @@ -66,7 +54,7 @@ class EVMIntents {

async approve(token: string) {
const erc20 = new Contract(token, erc20Abi, this.wallet);
await erc20.approve(perm2, MaxUint256);
await erc20.approve(PERMIT2_ADDRESS, MaxUint256);
}

toDeadline(expiration: number): number {
Expand All @@ -78,11 +66,11 @@ class EVMIntents {
// Not correct way to manage nonce?
const permit: PermitTransferFrom = {
permitted: {
token: token,
amount: swapOrder.amount
token: swapOrder.token,
amount: swapOrder.amount.valueOf()

},
spender: intentContract,
spender: swapOrder.emitter,
nonce: await this.wallet.getTransactionCount(),
deadline: deadline
};
Expand All @@ -92,7 +80,7 @@ class EVMIntents {
witnessType: { SwapOrder: swapOrder.PERMIT2_STRUCT },
witness: swapOrder.toStruct(),
}
const { domain, types, values } = SignatureTransfer.getPermitData(permit, perm2, 421614, witness)
const { domain, types, values } = SignatureTransfer.getPermitData(permit, PERMIT2_ADDRESS, 421614, witness)
const signature = await this.wallet._signTypedData(domain, types, values);
return [signature, permit]
}
Expand All @@ -108,19 +96,27 @@ class EVMIntents {
async fill(swapOrder: SwapOrder, repayAddress: string ): Promise<any> {
var value = BigInt(0);
if (swapOrder.toToken == "0x0000000000000000000000000000"){
value = swapOrder.amount
value = swapOrder.amount.valueOf()
} else {
// approve token
}
await this.intents.fill(swapOrder.toData(), repayAddress {value:value})
await this.intents.fill(swapOrder.toData(), repayAddress, {value:value})
}

async getOrder(txHash: string) {
async getBalance(token: string , address: string ): Promise<BigInt> {
if (token == "0x0000000000000000000000000000000000000000") {
return (await this.provider.getBalance(token)).toBigInt()
}

// TODO
return BigInt(0)
}

async getOrder(txHash: string) : Promise<SwapOrder> {
const receipt = await this.provider.getTransactionReceipt(txHash)
const iface = new Interface(this.abi);
receipt.logs.forEach((log) => {
if (log.address.toLowerCase() === intentContract.toLowerCase()) {
// Decode the log
if (log.address.toLowerCase() === this.intents.address.toLowerCase()) {
try {
const decodedLog = iface.parseLog(log);
if (decodedLog?.name == "SwapIntent") {
Expand All @@ -144,15 +140,13 @@ class EVMIntents {
}
}
});
throw "no order found"
}
}


const getProvider = () => {
const providerUrl = "https://sepolia-rollup.arbitrum.io/rpc";
return new JsonRpcProvider(providerUrl);
};



// ~/.cargo/bin/forge create --constructor-args "0xaa37dc.arbitrum" 10 0xEAbEb33723E2Df17De55906ddE1393C544204a8e 0x35D1B13C0DE523207c2106DE2e704E16EB1516b3 0x000000000022D473030F116dDEE9F6B43aC78BA3 --rpc-url https://sepolia-rollup.arbitrum.io/rpc/ --keystore .keystores/balanced_testnet_eth contracts/Intents/Intents.sol:Intents
// ~/.cargo/bin/forge verify-contract 0xDf01D1CD6675271c0F894049773AEA1E8b77607D contracts/Intents/Intents.sol:Intents --verifier-url 'https://api-sepolia.arbiscan.io/api' --etherscan-api-key "ZP4SRGNIXX7PRT8IMT1IQEPV86EX5326Q5" --num-of-optimizations 200 --compiler-version 0.8.21 --constructor-args $(~/.cargo/bin/cast abi-encode "constructor(string,uint16,address,address,address)" "nid" 10 0xEAbEb33723E2Df17De55906ddE1393C544204a8e 0xEAbEb33723E2Df17De55906ddE1393C544204a8e 0x000000000022D473030F116dDEE9F6B43aC78BA3)
// ~/.cargo/bin/forge create --constructor-args 0x0000000000000000000000000000000000000000d3af2663da51c10215000000 --rpc-url https://sepolia-rollup.arbitrum.io/rpc/ --keystore ../../contracts/evm/.keystores/balanced_testnet_eth src/Permit2.sol:Permit2

67 changes: 28 additions & 39 deletions sdk/src/sui-intents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Transaction } from '@mysten/sui/transactions';
import { SwapOrder } from './swap-order';

class SuiIntents {
export class SuiIntents {
client: SuiClient;
keypair: Ed25519Keypair;
packageId: string;
storageId: string;

constructor(packageId: string, net: 'mainnet' | 'testnet' | 'devnet' | 'localnet', keypair: Ed25519Keypair) {
constructor(packageId: string, storageId: string, net: 'mainnet' | 'testnet' | 'devnet' | 'localnet', keypair: Ed25519Keypair) {
const rpcUrl = getFullnodeUrl(net);
this.keypair = keypair;
this.client = new SuiClient({ url: rpcUrl });
this.packageId = packageId; // Sui package ID for the deployed Move contract
this.packageId = packageId;
this.storageId = storageId;
}

private async getCoin(tx: Transaction, coin: string, amount: bigint) {
Expand Down Expand Up @@ -49,20 +51,20 @@ class SuiIntents {
let coin: any;

if (swapOrder.token === "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI") {
coin = tx.splitCoins(tx.gas, [swapOrder.amount])[0];
coin = tx.splitCoins(tx.gas, [swapOrder.amount.valueOf()])[0];
} else {
coin = await this.getCoin(tx, swapOrder.token, swapOrder.amount);
coin = await this.getCoin(tx, swapOrder.token, swapOrder.amount.valueOf());
}

tx.moveCall({
target: `${this.packageId}::main::swap`,
arguments: [
tx.object("0x20499b147e56a123670f538c77afc2a20029643f28ce6b074183c8bfcf091d22"),
tx.object(this.storageId),
tx.pure.string(swapOrder.dstNID),
tx.object(coin),
tx.pure.string(swapOrder.toToken),
tx.pure.string(swapOrder.destinationAddress),
tx.pure.u128(swapOrder.toAmount),
tx.pure.u128(swapOrder.toAmount.valueOf()),
tx.pure.vector('vector<u8>', [].slice.call(swapOrder.data)),
],
typeArguments: [swapOrder.token],
Expand All @@ -77,25 +79,25 @@ class SuiIntents {
let coin: any;

if (swapOrder.toToken === "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI") {
coin = tx.splitCoins(tx.gas, [swapOrder.toAmount])[0];
coin = tx.splitCoins(tx.gas, [swapOrder.toAmount.valueOf()])[0];
} else {
coin = await this.getCoin(tx, swapOrder.toToken, swapOrder.toAmount);
coin = await this.getCoin(tx, swapOrder.toToken, swapOrder.toAmount.valueOf());
}

tx.moveCall({
target: `${this.packageId}::main::fill`,
arguments: [
tx.object("0x20499b147e56a123670f538c77afc2a20029643f28ce6b074183c8bfcf091d22"),
tx.pure.u128(swapOrder.id),
tx.pure.u128(swapOrder.id.valueOf()),
tx.pure.string(swapOrder.emitter),
tx.pure.string(swapOrder.srcNID),
tx.pure.string(swapOrder.dstNID),
tx.pure.string(swapOrder.creator),
tx.pure.string(swapOrder.destinationAddress),
tx.pure.string(swapOrder.token),
tx.pure.u128(swapOrder.amount),
tx.pure.u128(swapOrder.amount.valueOf()),
tx.pure.string(swapOrder.toToken),
tx.pure.u128(swapOrder.toAmount),
tx.pure.u128(swapOrder.toAmount.valueOf()),
tx.pure.vector('vector<u8>', []),
tx.object(coin),
tx.pure.string(repayAddress),
Expand All @@ -107,6 +109,20 @@ class SuiIntents {
return result;
}

async getBalance(token: string , address: string ): Promise<BigInt> {
const coins = await this.client.getCoins({
owner: this.keypair.getPublicKey().toSuiAddress(),
coinType: token,
});

var sum = BigInt(0);
for (const coin of coins.data) {
sum += BigInt(coin.balance);
}

return sum
}

async getOrder(txHash: string): Promise<SwapOrder> {
const transaction = await this.client.waitForTransaction({
digest: txHash,
Expand Down Expand Up @@ -134,30 +150,3 @@ class SuiIntents {
}
}


const packageId = "0x75ff8b82c302ab4d9358059b5a7bf423e2c3fa901e00dd6adeea9e27da0b6506"


const keypair = Ed25519Keypair.fromSecretKey("suiprivkey1qrdjntsdyuygqjsx3varvvx2hz6xkuk86zu2y255s0zw97uavl82xjul9z6");
console.log(keypair.getSecretKey())
console.log(keypair.getPublicKey().toSuiAddress())
const sui = new SuiIntents(packageId, "testnet", keypair)

const order = new SwapOrder(
BigInt(3),
packageId,
'arb',
'sui',
keypair.getPublicKey().toSuiAddress(),
'0x29a0918bee7a7e37d1a7d0613efc3f4455883ea217046f7db91d53e69c204589',
'0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI',
BigInt(10),
'0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI',
BigInt(100000),
new Uint8Array()
)

// sui.createOrder(order)
// sui.getOrder("5UTzxFAoWJD53jh5kGuzJW1HEhdGs5ffqkxWEY9D7THx")
sui.fillOrder(order, "as")

48 changes: 36 additions & 12 deletions sdk/src/swap-order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,30 @@ import { BigNumberish } from "ethers";

// Define the SwapOrder structure as a TypeScript interface
interface SwapOrderInterface {
id: BigNumberish; // uint256 -> bigint (to handle large numbers)
id: BigInt; // uint256 -> BigInt (to handle large numbers)
emitter: string; // string -> string
srcNID: string; // string -> string
dstNID: string; // string -> string
creator: string; // string -> string
destinationAddress: string; // string -> string
token: string; // string -> string
amount: bigint; // uint256 -> bigint
amount: BigInt; // uint256 -> BigInt
toToken: string; // string -> string
toAmount: bigint; // uint256 -> bigint
toAmount: BigInt; // uint256 -> BigInt
data: Uint8Array; // bytes -> Uint8Array for raw byte data
}

export class SwapOrder implements SwapOrderInterface {
id: BigNumberish;
id: BigInt;
emitter: string;
srcNID: string;
dstNID: string;
creator: string;
destinationAddress: string;
token: string;
amount: bigint;
amount: BigInt;
toToken: string;
toAmount: bigint;
toAmount: BigInt;
data: Uint8Array;

public PERMIT2_STRUCT = [
Expand All @@ -43,16 +43,16 @@ export class SwapOrder implements SwapOrderInterface {
];

constructor(
id: bigint,
id: BigInt,
emitter: string,
srcNID: string,
dstNID: string,
creator: string,
destinationAddress: string,
token: string,
amount: bigint,
amount: BigInt,
toToken: string,
toAmount: bigint,
toAmount: BigInt,
data: Uint8Array
) {
this.id = id;
Expand All @@ -70,16 +70,16 @@ export class SwapOrder implements SwapOrderInterface {

public toData(): any[] {
return [
this.id, // uint256 -> bigint
this.id, // uint256 -> BigInt
this.emitter, // string
this.srcNID, // string
this.dstNID, // string
this.creator, // string
this.destinationAddress, // string
this.token, // string
this.amount, // uint256 -> bigint
this.amount, // uint256 -> BigInt
this.toToken, // string
this.toAmount, // uint256 -> bigint
this.toAmount, // uint256 -> BigInt
this.data // bytes -> Uint8Array
];
}
Expand All @@ -100,4 +100,28 @@ export class SwapOrder implements SwapOrderInterface {
};
}

public equals(other: SwapOrder): boolean {
return (
this.id === other.id &&
this.emitter === other.emitter &&
this.srcNID === other.srcNID &&
this.dstNID === other.dstNID &&
this.creator === other.creator &&
this.destinationAddress === other.destinationAddress &&
this.token === other.token &&
this.amount === other.amount &&
this.toToken === other.toToken &&
this.toAmount === other.toAmount &&
this.arrayEquals(this.data, other.data)
);
}

private arrayEquals(a: Uint8Array, b: Uint8Array): boolean {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}

}
Loading

0 comments on commit 415fb94

Please sign in to comment.