Skip to content

Commit

Permalink
fix(LLC): solana tokens speculos tests to run with any tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
mikhd committed Feb 29, 2024
1 parent 7ff5252 commit 3e15b12
Showing 1 changed file with 45 additions and 47 deletions.
92 changes: 45 additions & 47 deletions libs/ledger-live-common/src/families/solana/specs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import invariant from "invariant";
import expect from "expect";
import { getCryptoCurrencyById, listTokensForCryptoCurrency } from "@ledgerhq/cryptoassets";
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets";
import { DeviceModelId } from "@ledgerhq/devices";
import {
botTest,
Expand All @@ -23,7 +23,6 @@ import { SYSTEM_ACCOUNT_RENT_EXEMPT, assertUnreachable } from "./utils";
import { getCurrentSolanaPreloadData } from "./js-preload-data";
import { sample } from "lodash/fp";
import BigNumber from "bignumber.js";
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
import { Account, TokenAccount } from "@ledgerhq/types-live";
import { SolanaRecipientAssociatedTokenAccountWillBeFunded } from "./errors";

Expand Down Expand Up @@ -475,23 +474,23 @@ const solana: AppSpec<Transaction> = {
},
},
{
name: "Transfer ~50% USDC with ATA creation",
name: "Transfer ~50% of spl token with ATA creation",
maxRun: 1,
deviceAction: acceptTransferTokensWithATACreationTransaction,
transaction: ({ account, bridge, siblings }) => {
const usdcToken = findUsdcTokenCurrency(account.currency);
invariant(usdcToken, "USDC token not listed");
transaction: ({ account, bridge, siblings, maxSpendable }) => {
invariant(maxSpendable.gt(0), "balance is 0");

const senderAccWithUsdc = findTokenSubAccount(account, usdcToken.id);
invariant(senderAccWithUsdc, "Sender account doesn't have USDC ATA");
const senderTokenAcc = findTokenSubAccountWithBalance(account);
invariant(senderTokenAcc, "Sender token account with available balance not found");

const siblingWithoutUsdc = siblings.find(acc => !findTokenSubAccount(acc, usdcToken.id));
invariant(siblingWithoutUsdc, "Recipient without USDC ATA was not found");
const token = senderTokenAcc.token;
const siblingWithoutToken = siblings.find(acc => !findTokenSubAccount(acc, token.id));
invariant(siblingWithoutToken, `Recipient without ${token.ticker} ATA not found`);

const amount = senderAccWithUsdc.balance.div(1.9 + 0.2 * Math.random()).integerValue();
const recipient = siblingWithoutUsdc.freshAddress;
const amount = senderTokenAcc.balance.div(1.9 + 0.2 * Math.random()).integerValue();
const recipient = siblingWithoutToken.freshAddress;
const transaction = bridge.createTransaction(account);
const subAccountId = senderAccWithUsdc.id;
const subAccountId = senderTokenAcc.id;

return {
transaction,
Expand All @@ -503,49 +502,53 @@ const solana: AppSpec<Transaction> = {
recipient: new SolanaRecipientAssociatedTokenAccountWillBeFunded(),
};
},
test: ({ account, accountBeforeTransaction, status }) => {
const usdcTokenAccAfterTx = findUsdcTokenAccount(account);
const usdcTokenAccBeforeTx = findUsdcTokenAccount(accountBeforeTransaction);
test: ({ account, accountBeforeTransaction, status, transaction }) => {
const tokenAccId = transaction.subAccountId;
const tokenAccAfterTx = account.subAccounts?.find(acc => acc.id === tokenAccId);
const tokenAccBeforeTx = accountBeforeTransaction.subAccounts?.find(
acc => acc.id === tokenAccId,
);

botTest("usdc balance decreased with operation", () =>
expect(usdcTokenAccAfterTx?.balance.toString()).toBe(
usdcTokenAccBeforeTx?.balance.minus(status.amount).toString(),
botTest("token balance decreased with operation", () =>
expect(tokenAccAfterTx?.balance.toString()).toBe(
tokenAccBeforeTx?.balance.minus(status.amount).toString(),
),
);
},
},
{
name: "Transfer ~50% USDC to existing ATA",
name: "Transfer ~50% of spl token to existing ATA",
maxRun: 1,
deviceAction: acceptTransferTokensTransaction,
transaction: ({ account, bridge, siblings }) => {
const usdcToken = findUsdcTokenCurrency(account.currency);
invariant(usdcToken, "USDC token not listed");

const senderAccWithUsdc = findTokenSubAccount(account, usdcToken.id);
invariant(senderAccWithUsdc, "Sender account doesn't have USDC token ATA");
transaction: ({ account, bridge, siblings, maxSpendable }) => {
invariant(maxSpendable.gt(0), "balance is 0");

const siblingWithUsdc = siblings.find(acc => findTokenSubAccount(acc, usdcToken.id));
invariant(siblingWithUsdc, "No siblings with USDC token ATA");
const senderTokenAcc = findTokenSubAccountWithBalance(account);
invariant(senderTokenAcc, "Sender token account with available balance not found");

const amount = senderAccWithUsdc.balance.div(1.9 + 0.2 * Math.random()).integerValue();
const recipient = siblingWithUsdc.freshAddress;
const token = senderTokenAcc.token;
const siblingTokenAccount = siblings.find(acc => findTokenSubAccount(acc, token.id));
invariant(siblingTokenAccount, `Sibling with ${token.ticker} token ATA not found`);

const amount = senderTokenAcc.balance.div(1.9 + 0.2 * Math.random()).integerValue();
const recipient = siblingTokenAccount.freshAddress;
const transaction = bridge.createTransaction(account);
const subAccountId = senderAccWithUsdc.id;

const subAccountId = senderTokenAcc.id;
return {
transaction,
updates: [{ subAccountId }, { recipient }, { amount }],
};
},
test: ({ account, accountBeforeTransaction, status }) => {
const usdcTokenAccAfterTx = findUsdcTokenAccount(account);
const usdcTokenAccBeforeTx = findUsdcTokenAccount(accountBeforeTransaction);
test: ({ account, accountBeforeTransaction, status, transaction }) => {
const tokenAccId = transaction.subAccountId;
const tokenAccAfterTx = account.subAccounts?.find(acc => acc.id === tokenAccId);
const tokenAccBeforeTx = accountBeforeTransaction.subAccounts?.find(
acc => acc.id === tokenAccId,
);

botTest("usdc balance decreased with operation", () =>
expect(usdcTokenAccAfterTx?.balance.toString()).toBe(
usdcTokenAccBeforeTx?.balance.minus(status.amount).toString(),
botTest("token balance decreased with operation", () =>
expect(tokenAccAfterTx?.balance.toString()).toBe(
tokenAccBeforeTx?.balance.minus(status.amount).toString(),
),
);
},
Expand Down Expand Up @@ -598,21 +601,16 @@ function expectCorrectBalanceChange(input: TransactionTestInput<Transaction>) {
);
}

function findUsdcTokenCurrency(currency: CryptoCurrency) {
const splTokens = listTokensForCryptoCurrency(currency);
return splTokens.find(token => token.ticker === "USDC");
}

function findTokenSubAccount(account: Account, tokenId: string) {
return account.subAccounts?.find(
acc => acc.type === "TokenAccount" && acc.token.id === tokenId,
) as TokenAccount | undefined;
}

function findUsdcTokenAccount(account: Account) {
const usdcToken = findUsdcTokenCurrency(account.currency);
if (!usdcToken) throw new Error("USDC token not found");
return findTokenSubAccount(account, usdcToken.id);
function findTokenSubAccountWithBalance(account: Account) {
return account.subAccounts?.find(acc => acc.type === "TokenAccount" && acc.balance.gt(0)) as
| TokenAccount
| undefined;
}

export default {
Expand Down

0 comments on commit 3e15b12

Please sign in to comment.