UNPKG

@eco-foundation/routes-sdk

Version:
928 lines (863 loc) 34.7 kB
import { describe, test, expect, beforeAll, beforeEach } from "vitest"; import { encodeFunctionData, erc20Abi, Hex, isAddress, zeroAddress } from "viem"; import { privateKeyToAccount } from "viem/accounts"; import { EcoProtocolAddresses, IntentType } from "@eco-foundation/routes-ts"; import { RoutesService, SolverQuote } from "../../src/index.js"; import { dateToTimestamp, getSecondsFromNow } from "../../src/utils.js"; import { ECO_SDK_CONFIG } from "../../src/config.js"; const account = privateKeyToAccount(process.env.VITE_TESTING_PK as Hex) describe("RoutesService", () => { let routesService: RoutesService; const creator = account.address beforeAll(() => { routesService = new RoutesService(); }) describe("customProtocolAddresses", () => { test("new chain addresses added and default chain addresses kept", () => { const customAddresses = { "3": { "IntentSource": "0x1234567890123456789012345678901234567890", "Inbox": "0x0987654321098765432109876543210987654321", }, "3-pre": { "IntentSource": "0x1234567890123456789012345678901234567890", "Inbox": "0x0987654321098765432109876543210987654321", } } as const; const routesService = new RoutesService({ customProtocolAddresses: customAddresses }) expect(routesService.getProtocolContractAddress(3, "IntentSource")).toBe("0x1234567890123456789012345678901234567890"); expect(routesService.getProtocolContractAddress(3, "Inbox")).toBe("0x0987654321098765432109876543210987654321"); expect(routesService.getProtocolContractAddress(10, "IntentSource")).toBe(EcoProtocolAddresses[`10${ECO_SDK_CONFIG.isPreprod ? '-pre' : ''}`].IntentSource); expect(routesService.getProtocolContractAddress(10, "Inbox")).toBe(EcoProtocolAddresses[`10${ECO_SDK_CONFIG.isPreprod ? '-pre' : ''}`].Inbox); }) test("non-overriden default addresses remain", () => { const customAddresses = { "10": { "IntentSource": "0x1234567890123456789012345678901234567890", "Inbox": "0x0987654321098765432109876543210987654321", }, "10-pre": { "IntentSource": "0x1234567890123456789012345678901234567890", "Inbox": "0x0987654321098765432109876543210987654321", }, } as const; const routesService = new RoutesService({ customProtocolAddresses: customAddresses }) expect(routesService.getProtocolContractAddress(10, "IntentSource")).toBe("0x1234567890123456789012345678901234567890"); expect(routesService.getProtocolContractAddress(10, "Inbox")).toBe("0x0987654321098765432109876543210987654321"); expect(routesService.getProtocolContractAddress(10, "HyperProver")).toBe(EcoProtocolAddresses[`10${ECO_SDK_CONFIG.isPreprod ? '-pre' : ''}`].HyperProver); }) }) describe("createSimpleIntent", () => { test("valid", async () => { const validIntent = routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBeGreaterThan(0); for (const token of validIntent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }) test("validCustomTokens", async () => { const validIntent = routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", spendingTokenLimit: BigInt(10000000), receivingToken: "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c", amount: BigInt(1000000), prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBeGreaterThan(0); for (const token of validIntent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }) test("validCreatorZeroAddress", async () => { const validIntent = routesService.createSimpleIntent({ creator: zeroAddress, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBeGreaterThan(0); for (const token of validIntent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }) test("invalidCreator", async () => { expect(() => routesService.createSimpleIntent({ creator: "0x", originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', })).toThrow("Invalid creator address"); }) test("invalidRecipient", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', recipient: "0x" })).toThrow("Invalid recipient address"); }) test("invalidChainIDs", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 10, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', })).toThrow("originChainID and destinationChainID cannot be the same"); }) test("invalidAmount", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(-1), prover: 'HyperProver', })).toThrow("Invalid amount"); }) test("invalidSpendingTokenLimit", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(-1), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', })).toThrow("Invalid spendingTokenLimit"); }) test("invalidExpiryTime", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', expiryTime: getSecondsFromNow(50), })).toThrow("Expiry time must be 60 seconds or more in the future"); }) test("invalidProverForChain", async () => { expect(() => routesService.createSimpleIntent({ creator, originChainID: 42161, destinationChainID: 10, spendingToken: RoutesService.getStableAddress(42161, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), prover: "MetaProver", })).toThrow(`No MetaProver exists on '42161${ECO_SDK_CONFIG.isPreprod && '-pre'}'`); }) }) describe("createIntent", () => { let transferData: Hex; beforeAll(() => { transferData = encodeFunctionData({ abi: erc20Abi, functionName: 'transfer', args: [creator, BigInt(1000000)] }) }) test("valid", async () => { const validIntent = routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", }) expect(validIntent).toBeDefined(); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBeGreaterThan(0); for (const token of validIntent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }) test("validCustomTokens", async () => { const validIntent = routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c", data: transferData, value: BigInt(0), }], callTokens: [{ token: "0x0555E30da8f98308EdB960aa94C0Db47230d2B9c", amount: BigInt(1000000), }], tokens: [{ token: "0x68f180fcCe6836688e9084f035309E29Bf0A2095", amount: BigInt(1000000), }], prover: "HyperProver", }) expect(validIntent).toBeDefined(); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBeGreaterThan(0); for (const token of validIntent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }) test("invalidCreator", async () => { expect(() => routesService.createIntent({ creator: "0x", originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid creator address"); }) test("invalidChainIDs", async () => { expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 10, calls: [{ target: RoutesService.getStableAddress(10, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("originChainID and destinationChainID cannot be the same"); }) test("invalidExpiryTime", async () => { expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", expiryTime: getSecondsFromNow(50), })).toThrow("Expiry time must be 60 seconds or more in the future"); }) test("invalidTokens", async () => { expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(-1), }], prover: "HyperProver", })).toThrow("Invalid tokens"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(100000) }], tokens: [], prover: "HyperProver", })).toThrow("Invalid tokens"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000) }], tokens: [{ token: "0x", amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid tokens"); }) test("invalidCallTokens", async () => { expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(-1), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid callTokens"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid callTokens"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: "0x", amount: BigInt(100000) }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid callTokens"); }) test("invalidCalls", async () => { expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: "0x0", data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid calls"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [{ target: RoutesService.getStableAddress(8453, "USDC"), data: transferData, value: BigInt(-1), }], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid calls"); expect(() => routesService.createIntent({ creator, originChainID: 10, destinationChainID: 8453, calls: [], callTokens: [{ token: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], prover: "HyperProver", })).toThrow("Invalid calls"); }) test("invalidProverForChain", async () => { expect(() => routesService.createIntent({ creator, originChainID: 42161, destinationChainID: 10, calls: [{ target: RoutesService.getStableAddress(10, "USDC"), data: transferData, value: BigInt(0), }], callTokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: BigInt(1000000), }], tokens: [{ token: RoutesService.getStableAddress(42161, "USDC"), amount: BigInt(1000000), }], prover: "MetaProver", })).toThrow(`No MetaProver exists on '42161${ECO_SDK_CONFIG.isPreprod && '-pre'}'`); }) }) describe("createNativeSendIntent", () => { test("valid", async () => { const validIntent = routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.salt).toBeDefined(); expect(validIntent.route.source).toBeDefined(); expect(validIntent.route.destination).toBeDefined(); expect(validIntent.route.inbox).toBeDefined(); expect(isAddress(validIntent.route.inbox, { strict: false })).toBe(true); expect(validIntent.route.calls).toBeDefined(); expect(validIntent.route.calls.length).toBeGreaterThan(0); for (const call of validIntent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); expect(call.value).toBe(BigInt(1000000)); } expect(validIntent.route.tokens).toBeDefined(); expect(validIntent.route.tokens.length).toBe(0); expect(validIntent.reward).toBeDefined(); expect(validIntent.reward.creator).toBeDefined(); expect(isAddress(validIntent.reward.creator, { strict: false })).toBe(true); expect(validIntent.reward.prover).toBeDefined(); expect(isAddress(validIntent.reward.prover, { strict: false })).toBe(true); expect(validIntent.reward.deadline).toBeDefined(); expect(validIntent.reward.nativeValue).toBeDefined(); expect(validIntent.reward.nativeValue).toBe(BigInt("1000000000000000000")); expect(validIntent.reward.tokens).toBeDefined(); expect(validIntent.reward.tokens.length).toBe(0); }) test("validWithCustomRecipient", async () => { const recipient = "0x1234567890123456789012345678901234567890"; const validIntent = routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH recipient, prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent.route).toBeDefined(); expect(validIntent.route.calls.length).toBe(1); expect(validIntent.route.calls[0]!.target).toBe(recipient); expect(validIntent.route.calls[0]!.value).toBe(BigInt(1000000)); expect(validIntent.reward.nativeValue).toBe(BigInt("1000000000000000000")); }) test("validCreatorZeroAddress", async () => { const validIntent = routesService.createNativeSendIntent({ creator: zeroAddress, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', }); expect(validIntent).toBeDefined(); expect(validIntent.reward.creator).toBe(zeroAddress); }) test("invalidCreator", async () => { expect(() => routesService.createNativeSendIntent({ creator: "0x", originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', })).toThrow("Invalid creator address"); }) test("invalidRecipient", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', recipient: "0x" })).toThrow("Invalid recipient address"); }) test("invalidChainIDs", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 10, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', })).toThrow("originChainID and destinationChainID cannot be the same"); }) test("invalidAmount", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt(-1), limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', })).toThrow("Invalid amount"); }) test("invalidLimit", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt(-1), prover: 'HyperProver', })).toThrow("Invalid limit"); }) test("invalid:insufficientLimit", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("999999"), // 0.000000999999 ETH prover: 'HyperProver', })).toThrow("Insufficient limit"); }) test("invalidExpiryTime", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 10, destinationChainID: 8453, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: 'HyperProver', expiryTime: getSecondsFromNow(50), })).toThrow("Expiry time must be 60 seconds or more in the future"); }) test("invalidProverForChain", async () => { expect(() => routesService.createNativeSendIntent({ creator, originChainID: 42161, destinationChainID: 10, amount: BigInt("1000000"), // 0.000000000001 ETH limit: BigInt("1000000000000000000"), // 1 ETH prover: "MetaProver", })).toThrow(`No MetaProver exists on '42161${ECO_SDK_CONFIG.isPreprod && '-pre'}'`); }) }) describe("applyQuoteToIntent", () => { let validIntent: IntentType; let validQuote: SolverQuote; beforeAll(() => { validIntent = routesService.createSimpleIntent({ creator, originChainID: 10, destinationChainID: 8453, spendingToken: RoutesService.getStableAddress(10, "USDC"), spendingTokenLimit: BigInt(10000000), receivingToken: RoutesService.getStableAddress(8453, "USDC"), amount: BigInt(1000000), prover: 'HyperProver', }); }) beforeEach(() => { validQuote = { quoteData: { tokens: [{ token: RoutesService.getStableAddress(10, "USDC"), amount: "1000000", }], nativeValue: "0", expiryTime: dateToTimestamp(getSecondsFromNow(60)).toString(), estimatedFulfillTimeSec: 2, } }; }); test("valid", () => { const intent = routesService.applyQuoteToIntent({ intent: validIntent, quote: validQuote }); expect(intent).toBeDefined(); expect(intent).toBeDefined(); expect(intent.route).toBeDefined(); expect(intent.route.salt).toBeDefined(); expect(intent.route.source).toBeDefined(); expect(intent.route.destination).toBeDefined(); expect(intent.route.inbox).toBeDefined(); expect(isAddress(intent.route.inbox, { strict: false })).toBe(true); expect(intent.route.calls).toBeDefined(); expect(intent.route.calls.length).toBeGreaterThan(0); for (const call of intent.route.calls) { expect(call.target).toBeDefined(); expect(isAddress(call.target, { strict: false })).toBe(true); expect(call.data).toBeDefined(); expect(call.value).toBeDefined(); } expect(intent.reward).toBeDefined(); expect(intent.reward.creator).toBeDefined(); expect(isAddress(intent.reward.creator, { strict: false })).toBe(true); expect(intent.reward.prover).toBeDefined(); expect(isAddress(intent.reward.prover, { strict: false })).toBe(true); expect(intent.reward.deadline).toBeDefined(); expect(intent.reward.nativeValue).toBeDefined(); expect(intent.reward.tokens).toBeDefined(); expect(intent.reward.tokens.length).toBeGreaterThan(0); for (const token of intent.reward.tokens) { expect(token.token).toBeDefined(); expect(isAddress(token.token, { strict: false })).toBe(true); expect(token.amount).toBeDefined(); expect(token.amount).toBeGreaterThan(0); } }); test("invalid quote data", () => { const intent = validIntent; const quote: SolverQuote = { ...validQuote, quoteData: { ...validQuote.quoteData, tokens: [], } }; expect(() => routesService.applyQuoteToIntent({ intent, quote })).toThrow("Invalid quoteData: tokens array must have length greater than 0"); }); }); })