@ledgerhq/coin-aptos
Version:
Ledger Aptos Coin integration
1,165 lines • 96 kB
JavaScript
"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