UNPKG

@ledgerhq/coin-filecoin

Version:
114 lines (102 loc) 4.15 kB
import { validateIntent } from "./validateIntent"; jest.mock("@ledgerhq/logs"); // Mock the iso-filecoin-backed validator so synthetic test addresses pass. // validateAddress.unit.test.ts exercises the real delegation path. jest.mock("../network/addresses", () => ({ validateAddress: (input: string) => ({ isValid: input !== "NOT-VALID", parsedAddress: { toString: () => input }, }), isRecipientValidForTokenTransfer: () => true, })); const NATIVE_BALANCES = [ { value: 5_000_000_000_000_000_000n, asset: { type: "native" as const }, locked: 0n }, ]; const baseIntent = { intentType: "transaction" as const, type: "send" as const, sender: "f1abjxfbp274xpdqcpuaykwkfb43omjotacm2p3za", recipient: "f1z4nykg7q6q5qnxs7h4zknhlqbqhq5jxcqm5qw4y", amount: 1_000_000_000_000_000_000n, asset: { type: "native" as const }, useAllAmount: false, }; describe("validateIntent", () => { it("returns no errors for valid native intent with sufficient balance", async () => { const result = await validateIntent(baseIntent, NATIVE_BALANCES); expect(result.errors).toEqual({}); }); it("returns recipient error for invalid address", async () => { const intent = { ...baseIntent, recipient: "NOT-VALID" }; const result = await validateIntent(intent, NATIVE_BALANCES); expect(result.errors.recipient).toBeInstanceOf(Error); }); it("returns amount error when amount exceeds balance", async () => { const intent = { ...baseIntent, amount: 100_000_000_000_000_000_000n }; const result = await validateIntent(intent, NATIVE_BALANCES); expect(result.errors.amount).toBeInstanceOf(Error); }); it("returns NotEnoughBalance (not AmountRequired) for send-max when fees consume the balance", async () => { const intent = { ...baseIntent, useAllAmount: true }; const result = await validateIntent(intent, NATIVE_BALANCES, { value: 5_000_000_000_000_000_000n, }); expect(result.errors.amount?.name).toBe("NotEnoughBalance"); }); it("emits feeTooHigh warning when fees exceed balance", async () => { const lowBalance = [{ value: 100n, asset: { type: "native" as const }, locked: 0n }]; const smallIntent = { ...baseIntent, amount: 1n }; const result = await validateIntent(smallIntent, lowBalance, { value: 200n }); expect(result.warnings.feeTooHigh).toBeInstanceOf(Error); }); it("checks token balance for erc20 intent", async () => { const tokenIntent = { ...baseIntent, amount: 5_000n, asset: { type: "erc20" as const, assetReference: "0xcontract", }, }; const tokenBalances = [ ...NATIVE_BALANCES, { value: 3_000n, asset: { type: "erc20" as const, assetReference: "0xcontract" }, }, ]; const result = await validateIntent(tokenIntent, tokenBalances); expect(result.errors.amount).toBeInstanceOf(Error); // 5000 > 3000 }); it("computes send-max amount as the full token balance for erc20 intent", async () => { const tokenIntent = { ...baseIntent, amount: 0n, useAllAmount: true, asset: { type: "erc20" as const, assetReference: "0xcontract" }, }; const tokenBalances = [ ...NATIVE_BALANCES, { value: 3_000n, asset: { type: "erc20" as const, assetReference: "0xcontract" } }, ]; const result = await validateIntent(tokenIntent, tokenBalances); expect(result.errors.amount).toBeUndefined(); expect(result.amount).toBe(3_000n); }); it("rejects erc20 intent when native balance is insufficient to cover fees", async () => { const tokenIntent = { ...baseIntent, amount: 100n, asset: { type: "erc20" as const, assetReference: "0xcontract", }, }; const balancesWithLowNative = [ { value: 10n, asset: { type: "native" as const }, locked: 0n }, { value: 1_000n, asset: { type: "erc20" as const, assetReference: "0xcontract" } }, ]; const result = await validateIntent(tokenIntent, balancesWithLowNative, { value: 500n }); expect(result.errors.amount).toBeInstanceOf(Error); // fees 500 > native 10 }); });