UNPKG

@ledgerhq/coin-aptos

Version:
1,165 lines 96 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsHelpers_1 = require("@ledgerhq/coin-framework/bridge/jsHelpers"); const index_1 = require("@ledgerhq/cryptoassets/index"); const account_1 = require("@ledgerhq/coin-framework/account"); const index_2 = require("@ledgerhq/coin-framework/account/index"); const network_1 = require("../../network"); const synchronisation_1 = require("../../bridge/synchronisation"); const bignumber_js_1 = __importDefault(require("bignumber.js")); const bridge_fixture_1 = require("../../bridge/bridge.fixture"); const logic_1 = require("../../bridge/logic"); const live_env_1 = require("@ledgerhq/live-env"); jest.mock("@ledgerhq/coin-framework/account", () => { const originalModule = jest.requireActual("@ledgerhq/coin-framework/account"); const partialMockedModule = Object.keys(originalModule).reduce((pre, methodName) => { pre[methodName] = jest.fn(); return pre; }, {}); return { ...partialMockedModule, // mock all except these encodeAccountId: originalModule.encodeAccountId, decodeAccountId: originalModule.decodeAccountId, encodeTokenAccountId: originalModule.encodeTokenAccountId, }; }); const mockedDecodeTokenAccountId = jest.mocked(account_1.decodeTokenAccountId); jest.mock("../../network"); let mockedAptosAPI; jest.mock("@ledgerhq/coin-framework/bridge/jsHelpers"); jest.mock("invariant", () => jest.fn()); jest.mock("../../bridge/logic"); describe("getAccountShape", () => { beforeEach(() => { mockedAptosAPI = jest.mocked(network_1.AptosAPI); }); afterEach(() => { jest.resetAllMocks(); }); it("account with xpub", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", initialAccount: { id: "1:1:1:1:aptos", xpub: "address", seedIdentifier: "1", derivationMode: "", index: 0, freshAddress: "address", freshAddressPath: "", used: true, balance: (0, bignumber_js_1.default)(10), spendableBalance: (0, bignumber_js_1.default)(10), creationDate: new Date(), blockHeight: 0, currency: (0, index_1.getCryptoCurrencyById)("aptos"), operationsCount: 0, operations: [], pendingOperations: [], lastSyncDate: new Date(), balanceHistoryCache: {}, swapHistory: [], }, }, {}); expect(account.xpub).toEqual("address"); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("account without xpub", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", initialAccount: { id: "1:1:1:1:aptos", seedIdentifier: "1", derivationMode: "", index: 0, freshAddress: "address", freshAddressPath: "", used: true, balance: (0, bignumber_js_1.default)(10), spendableBalance: (0, bignumber_js_1.default)(10), creationDate: new Date(), blockHeight: 0, currency: (0, index_1.getCryptoCurrencyById)("aptos"), operationsCount: 0, operations: [], pendingOperations: [], lastSyncDate: new Date(), balanceHistoryCache: {}, swapHistory: [], }, }, {}); expect(account.xpub).toEqual("1"); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("without initialAccount", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", }, {}); expect(account.xpub).toEqual(""); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("initialAccount with operations", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", initialAccount: { id: "1:1:1:1:aptos", seedIdentifier: "1", derivationMode: "", index: 0, freshAddress: "address", freshAddressPath: "", used: true, balance: (0, bignumber_js_1.default)(10), spendableBalance: (0, bignumber_js_1.default)(10), creationDate: new Date(), blockHeight: 0, currency: (0, index_1.getCryptoCurrencyById)("aptos"), operationsCount: 0, operations: [], pendingOperations: [], lastSyncDate: new Date(), balanceHistoryCache: {}, swapHistory: [], }, }, {}); expect(account.xpub).toEqual("1"); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("initialAccount with operations with extra", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", initialAccount: { id: "1:1:1:1:aptos", seedIdentifier: "1", derivationMode: "", index: 0, freshAddress: "address", freshAddressPath: "", used: true, balance: (0, bignumber_js_1.default)(10), spendableBalance: (0, bignumber_js_1.default)(10), creationDate: new Date(), blockHeight: 0, currency: (0, index_1.getCryptoCurrencyById)("aptos"), operationsCount: 0, operations: [], pendingOperations: [], lastSyncDate: new Date(), balanceHistoryCache: {}, swapHistory: [], }, }, {}); expect(account.xpub).toEqual("1"); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("get publicKey from rest", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(0), transactions: [], blockHeight: 0, })); mockedAptosAPI.mockImplementation(() => ({ getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); jest.mocked(jsHelpers_1.mergeOps).mockReturnValue([]); jest.mocked(logic_1.txsToOps).mockReturnValue([[], [], []]); const account = await (0, synchronisation_1.getAccountShape)({ id: "1", address: "address", currency: (0, index_1.getCryptoCurrencyById)("aptos"), derivationMode: "", index: 0, xpub: "address", derivationPath: "", deviceId: "1", initialAccount: { id: "1:1:1:1:aptos", seedIdentifier: "1", derivationMode: "", index: 0, freshAddress: "address", freshAddressPath: "", used: true, balance: (0, bignumber_js_1.default)(10), spendableBalance: (0, bignumber_js_1.default)(10), creationDate: new Date(), blockHeight: 0, currency: (0, index_1.getCryptoCurrencyById)("aptos"), operationsCount: 0, operations: [], pendingOperations: [], lastSyncDate: new Date(), balanceHistoryCache: {}, swapHistory: [], }, rest: { publicKey: "restPublicKey" }, }, {}); expect(account.xpub).toEqual("restPublicKey"); expect(mockedAptosAPI).toHaveBeenCalledTimes(1); expect(mockGetAccountSpy).toHaveBeenCalledWith("address"); }); it("initialAccount with operations with subOperations", async () => { const mockGetAccountInfo = jest.fn().mockImplementation(async () => ({ balance: (0, bignumber_js_1.default)(68254118), transactions: [ { version: "2532591427", hash: "0x3f35", state_change_hash: "0xb480", event_root_hash: "0x3fa1", state_checkpoint_hash: null, gas_used: "12", success: true, vm_status: "Executed successfully", accumulator_root_hash: "0x319f", changes: [ { address: "0x4e5e", state_key_hash: "0x3c0c", data: { type: "0x1::coin::CoinStore<0xd111::staked_coin::StakedAptos>", data: { coin: { value: "4000000", }, deposit_events: { counter: "9", guid: { id: { addr: "0x4e5e", creation_num: "4", }, }, }, frozen: false, withdraw_events: { counter: "6", guid: { id: { addr: "0x4e5e", creation_num: "5", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x1709", data: { type: "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", data: { coin: { value: "68254118", }, deposit_events: { counter: "46", guid: { id: { addr: "0xa0d8", creation_num: "2", }, }, }, frozen: false, withdraw_events: { counter: "89", guid: { id: { addr: "0xa0d8", creation_num: "3", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x5520", data: { type: "0x1::coin::CoinStore<0xd111::staked_coin::StakedAptos>", data: { coin: { value: "1000000", }, deposit_events: { counter: "7", guid: { id: { addr: "0xa0d8", creation_num: "10", }, }, }, frozen: false, withdraw_events: { counter: "13", guid: { id: { addr: "0xa0d8", creation_num: "11", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x6f1e", data: { type: "0x1::account::Account", data: { authentication_key: "0xa0d8", coin_register_events: { counter: "5", guid: { id: { addr: "0xa0d8", creation_num: "0", }, }, }, guid_creation_num: "12", key_rotation_events: { counter: "0", guid: { id: { addr: "0xa0d8", creation_num: "1", }, }, }, rotation_capability_offer: { for: { vec: [], }, }, sequence_number: "122", signer_capability_offer: { for: { vec: [], }, }, }, }, type: "write_resource", }, { state_key_hash: "0x6e4b", handle: "0x1b85", key: "0x0619", value: "0x1ddaf8da3b1497010000000000000000", data: null, type: "write_table_item", }, ], sender: "0xa0d8", sequence_number: "121", max_gas_amount: "12", gas_unit_price: "100", expiration_timestamp_secs: "1743177404", payload: { function: "0x1::aptos_account::transfer_coins", type_arguments: ["0xd111::staked_coin::StakedAptos"], arguments: ["0x4e5e", "1500000"], type: "entry_function_payload", }, signature: { public_key: "0x474d", signature: "0x0ad8", type: "ed25519_signature", }, events: [ { guid: { creation_number: "11", account_address: "0xa0d8", }, sequence_number: "12", type: "0x1::coin::WithdrawEvent", data: { amount: "1500000", }, }, { guid: { creation_number: "4", account_address: "0x4e5e", }, sequence_number: "8", type: "0x1::coin::DepositEvent", data: { amount: "1500000", }, }, { guid: { creation_number: "0", account_address: "0x0", }, sequence_number: "0", type: "0x1::transaction_fee::FeeStatement", data: { execution_gas_units: "6", io_gas_units: "6", storage_fee_octas: "0", storage_fee_refund_octas: "0", total_charge_gas_units: "12", }, }, ], timestamp: "1743177360481259", type: "user_transaction", block: { height: 311948147, hash: "0x6d02", }, }, { version: "2532549325", hash: "0x9a6b", state_change_hash: "0xa424", event_root_hash: "0x0321", state_checkpoint_hash: null, gas_used: "12", success: true, vm_status: "Executed successfully", accumulator_root_hash: "0xede9", changes: [ { address: "0x4e5e", state_key_hash: "0x3c0c", data: { type: "0x1::coin::CoinStore<0xd111::staked_coin::StakedAptos>", data: { coin: { value: "2500000", }, deposit_events: { counter: "8", guid: { id: { addr: "0x4e5e", creation_num: "4", }, }, }, frozen: false, withdraw_events: { counter: "6", guid: { id: { addr: "0x4e5e", creation_num: "5", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x1709", data: { type: "0x1::coin::CoinStore<0x1::aptos_coin::AptosCoin>", data: { coin: { value: "68255318", }, deposit_events: { counter: "46", guid: { id: { addr: "0xa0d8", creation_num: "2", }, }, }, frozen: false, withdraw_events: { counter: "89", guid: { id: { addr: "0xa0d8", creation_num: "3", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x5520", data: { type: "0x1::coin::CoinStore<0xd111::staked_coin::StakedAptos>", data: { coin: { value: "2500000", }, deposit_events: { counter: "7", guid: { id: { addr: "0xa0d8", creation_num: "10", }, }, }, frozen: false, withdraw_events: { counter: "12", guid: { id: { addr: "0xa0d8", creation_num: "11", }, }, }, }, }, type: "write_resource", }, { address: "0xa0d8", state_key_hash: "0x6f1e", data: { type: "0x1::account::Account", data: { authentication_key: "0xa0d8", coin_register_events: { counter: "5", guid: { id: { addr: "0xa0d8", creation_num: "0", }, }, }, guid_creation_num: "12", key_rotation_events: { counter: "0", guid: { id: { addr: "0xa0d8", creation_num: "1", }, }, }, rotation_capability_offer: { for: { vec: [], }, }, sequence_number: "121", signer_capability_offer: { for: { vec: [], }, }, }, }, type: "write_resource", }, { state_key_hash: "0x6e4b", handle: "0x1b85", key: "0x0619", value: "0xe86e0039581497010000000000000000", data: null, type: "write_table_item", }, ], sender: "0xa0d8", sequence_number: "120", max_gas_amount: "12", gas_unit_price: "100", expiration_timestamp_secs: "1743176706", payload: { function: "0x1::aptos_account::transfer_coins", type_arguments: ["0xd111::staked_coin::StakedAptos"], arguments: ["0x4e5e", "2500000"], type: "entry_function_payload", }, signature: { public_key: "0x474d", signature: "0xb70e", type: "ed25519_signature", }, events: [ { guid: { creation_number: "11", account_address: "0xa0d8", }, sequence_number: "11", type: "0x1::coin::WithdrawEvent", data: { amount: "2500000", }, }, { guid: { creation_number: "4", account_address: "0x4e5e", }, sequence_number: "7", type: "0x1::coin::DepositEvent", data: { amount: "2500000", }, }, { guid: { creation_number: "0", account_address: "0x0", }, sequence_number: "0", type: "0x1::transaction_fee::FeeStatement", data: { execution_gas_units: "6", io_gas_units: "6", storage_fee_octas: "0", storage_fee_refund_octas: "0", total_charge_gas_units: "12", }, }, ], timestamp: "1743176594693251", type: "user_transaction", block: { height: 311942427, hash: "0x8655", }, }, ], blockHeight: 316278241, })); const TOKEN_CONTRACT_ADDRESS = "0xd111::staked_coin::StakedAptos"; const mockGetBalances = jest .fn() .mockResolvedValue([{ contractAddress: TOKEN_CONTRACT_ADDRESS, amount: (0, bignumber_js_1.default)(1234567) }]); mockedAptosAPI.mockImplementation(() => ({ getBalances: mockGetBalances, getAccountInfo: mockGetAccountInfo, })); const mockGetAccountSpy = jest.spyOn({ getAccount: mockGetAccountInfo }, "getAccount"); mockedDecodeTokenAccountId.mockReturnValue({ token: { type: "TokenCurrency", id: "aptos/coin/dstapt_0xd111::staked_coin::stakedaptos", contractAddress: "0xd111::staked_coin::StakedAptos", parentCurrency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], explorerViews: [ { address: "https://explorer.aptoslabs.com/account/$address?network=mainnet", tx: "https://explorer.aptoslabs.com/txn/$hash?network=mainnet", }, ], }, name: "dstAPT", tokenType: "coin", ticker: "dstAPT", disableCountervalue: false, delisted: false, units: [ { name: "dstAPT", code: "dstAPT", magnitude: 8, }, ], }, accountId: "js:2:aptos:6415:aptos", }); const operations = [ { id: "js:2:aptos:474d:aptos-0x3f35-OUT", hash: "0x3f35", type: "FEES", value: (0, bignumber_js_1.default)(1200), fee: (0, bignumber_js_1.default)(1200), blockHash: "0x6d02", blockHeight: 311948147, senders: ["0xa0d8"], recipients: ["0x4e5e"], accountId: "js:2:aptos:474d:aptos", date: new Date("2025-03-28T15:56:00.481Z"), extra: { version: "2532591427", }, transactionSequenceNumber: 121, hasFailed: false, }, { id: "js:2:aptos:474d:aptos-0x9a6b-OUT", hash: "0x9a6b", type: "FEES", value: (0, bignumber_js_1.default)(1200), fee: (0, bignumber_js_1.default)(1200), blockHash: "0x8655", blockHeight: 311942427, senders: ["0xa0d8"], recipients: ["0x4e5e"], accountId: "js:2:aptos:474d:aptos", date: new Date("2025-03-28T15:43:14.693Z"), extra: { version: "2532549325", }, transactionSequenceNumber: 120, hasFailed: false, }, ]; const tokenOperations = [ { id: "js:2:aptos:474d:aptos-0x3f35-OUT", hash: "0x3f35", type: "OUT", value: (0, bignumber_js_1.default)(1500000), fee: (0, bignumber_js_1.default)(1200), blockHash: "0x6d02", blockHeight: 311948147, senders: ["0xa0d8"], recipients: ["0x4e5e"], accountId: "js:2:aptos:474d:aptos+aptos%2Fcoin%2Fdstapt~!underscore!~0xd111%3A%3Astaked~!underscore!~coin%3A%3Astakedaptos", date: new Date("2025-03-28T15:56:00.481Z"), extra: { version: "2532591427", }, transactionSequenceNumber: 121, hasFailed: false, }, { id: "js:2:aptos:474d:aptos-0x9a6b-OUT", hash: "0x9a6b", type: "OUT", value: (0, bignumber_js_1.default)(2500000), fee: (0, bignumber_js_1.default)(1200), blockHash: "0x8655", blockHeight: 311942427, senders: ["0xa0d8"], recipients: ["0x4e5e"], accountId: "js:2:aptos:474d:aptos+aptos%2Fcoin%2Fdstapt~!underscore!~0xd111%3A%3Astaked~!underscore!~coin%3A%3Astakedaptos", date: new Date("2025-03-28T15:43:14.693Z"), extra: { version: "2532549325", }, transactionSequenceNumber: 120, hasFailed: false, }, ]; const stakingOperations = []; jest.mocked(jsHelpers_1.mergeOps).mockReturnValue(operations); jest.mocked(logic_1.txsToOps).mockReturnValue([operations, tokenOperations, stakingOperations]); const info = { currency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], }, index: 0, address: "0xa0d8", derivationPath: "44'/637'/0'", derivationMode: "aptos", initialAccount: { type: "Account", id: "js:2:aptos:474d:aptos", used: true, seedIdentifier: "3086", derivationMode: "aptos", index: 0, freshAddress: "0xa0d8", freshAddressPath: "44'/637'/0'/0'/0'", blockHeight: 316272224, creationDate: "2025-01-16T14:17:41.076Z", balance: (0, bignumber_js_1.default)(68254118), spendableBalance: (0, bignumber_js_1.default)(68254118), operations: [], operationsCount: 0, pendingOperations: [], currency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], }, lastSyncDate: new Date(), swapHistory: [], balanceHistoryCache: index_2.emptyHistoryCache, xpub: "474d", subAccounts: [ { type: "TokenAccount", id: "js:2:aptos:474d:aptos+aptos%2Fcoin%2Fdstapt~!underscore!~0xd111%3A%3Astaked~!underscore!~coin%3A%3Astakedaptos", parentId: "js:2:aptos:474d:aptos", token: { type: "TokenCurrency", id: "aptos/coin/dstapt_0xd111::staked_coin::stakedaptos", contractAddress: "0xd111::staked_coin::StakedAptos", parentCurrency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], }, name: "dstAPT", tokenType: "coin", ticker: "dstAPT", disableCountervalue: false, delisted: false, units: [ { name: "dstAPT", code: "dstAPT", magnitude: 8, }, ], }, balance: (0, bignumber_js_1.default)(5000000), spendableBalance: (0, bignumber_js_1.default)(5000000), creationDate: "2025-03-11T09:33:46.840Z", operations: [], operationsCount: 0, pendingOperations: [], swapHistory: [], balanceHistoryCache: index_2.emptyHistoryCache, }, ], }, }; const result = await (0, synchronisation_1.getAccountShape)(info, {}); expect(result.operations).toHaveLength(2); expect(result.operations?.at(0)?.subOperations).toHaveLength(2); expect(result.operations?.at(1)?.subOperations).toHaveLength(2); expect(result.subAccounts).toHaveLength(1); expect(mockedAptosAPI).toHaveBeenCalledTimes(2); expect(mockGetAccountSpy).toHaveBeenCalledWith("0xa0d8"); }); }); describe("mergeSubAccounts", () => { const initialSubAccount = { type: "TokenAccount", id: "subAccountId", parentId: "accountId", token: { type: "TokenCurrency", id: "aptos/coin/dstapt_0xd111::staked_coin::stakedaptos", contractAddress: "0xd111::staked_coin::StakedAptos", parentCurrency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], explorerViews: [ { address: "https://explorer.aptoslabs.com/account/$address?network=mainnet", tx: "https://explorer.aptoslabs.com/txn/$hash?network=mainnet", }, ], }, name: "dstAPT", tokenType: "coin", ticker: "dstAPT", disableCountervalue: false, delisted: false, units: [ { name: "dstAPT", code: "dstAPT", magnitude: 8, }, ], }, balance: (0, bignumber_js_1.default)(100), spendableBalance: (0, bignumber_js_1.default)(100), creationDate: new Date(), operationsCount: 0, operations: [], pendingOperations: [], balanceHistoryCache: index_2.emptyHistoryCache, swapHistory: [], }; const initialAccount = (0, bridge_fixture_1.createFixtureAccount)({ subAccounts: [initialSubAccount], }); it("return new subAccount if no old subAccounts", () => { expect((0, synchronisation_1.mergeSubAccounts)(undefined, [initialSubAccount])).toEqual([initialSubAccount]); }); it("merge subAccounts properly if initialAccount has the same as new subAccounts", () => { expect((0, synchronisation_1.mergeSubAccounts)(initialAccount, [initialSubAccount])).toEqual([initialSubAccount]); }); it("adds new sub account to initialAccount properly", () => { const newSubAccount = { type: "TokenAccount", id: "js:2:aptos:474d:aptos+aptos%2Ffungible~!underscore!~asset%2Fcellana~!underscore!~0x2ebb", parentId: "js:2:aptos:474d:aptos", token: { type: "TokenCurrency", id: "aptos/fungible_asset/cellana_0x2ebb", contractAddress: "0x2ebb", parentCurrency: { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], explorerViews: [ { address: "https://explorer.aptoslabs.com/account/$address?network=mainnet", tx: "https://explorer.aptoslabs.com/txn/$hash?network=mainnet", }, ], }, name: "CELLANA", tokenType: "fungible_asset", ticker: "CELL", disableCountervalue: false, delisted: false, units: [ { name: "CELLANA", code: "CELL", magnitude: 8, }, ], }, balance: (0, bignumber_js_1.default)(22980368), spendableBalance: (0, bignumber_js_1.default)(22980368), creationDate: new Date(), operationsCount: 0, operations: [], pendingOperations: [], swapHistory: [], balanceHistoryCache: index_2.emptyHistoryCache, }; expect((0, synchronisation_1.mergeSubAccounts)(initialAccount, [newSubAccount])).toEqual([ initialSubAccount, newSubAccount, ]); }); it("merge subAccounts properly when new subAccounts is different", () => { expect((0, synchronisation_1.mergeSubAccounts)(initialAccount, [{ ...initialSubAccount, balance: (0, bignumber_js_1.default)(150) }])).toEqual([{ ...initialSubAccount, balance: (0, bignumber_js_1.default)(150) }]); }); }); describe("getSubAccountShape", () => { beforeEach(() => { mockedAptosAPI = jest.mocked(network_1.AptosAPI); }); afterEach(() => { jest.resetAllMocks(); }); const currency = { type: "CryptoCurrency", id: "aptos", coinType: 637, name: "Aptos", managerAppName: "Aptos", ticker: "APT", scheme: "aptos", color: "#231F20", family: "aptos", units: [ { name: "APT", code: "APT", magnitude: 8, }, ], explorerViews: [ { address: "https://explorer.aptoslabs.com/account/$address?network=mainnet", tx: "https://explorer.aptoslabs.com/txn/$hash?network=mainnet", }, ], }; const address = "0xa0d8"; const parentId = "js:2:aptos:474d:aptos"; const token = { type: "TokenCurrency", id: "aptos/coin/dstapt_0xd111::staked_coin::stakedaptos", contractAddress: "0xd111::staked_coin::StakedAptos", parentCur