@ledgerhq/coin-hedera
Version:
Ledger Hedera Coin integration
250 lines (225 loc) • 8.2 kB
text/typescript
import BigNumber from "bignumber.js";
import { HEDERA_TRANSACTION_MODES } from "../constants";
import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
import {
getMockedERC20TokenCurrency,
getMockedHTSTokenCurrency,
} from "../test/fixtures/currency.fixture";
import { getMockedTransaction } from "../test/fixtures/transaction.fixture";
import { buildOptimisticOperation } from "./buildOptimisticOperation";
describe("buildOptimisticOperation", () => {
it("builds optimistic operation for token association", async () => {
const mockedAccount = getMockedAccount();
const mockedToken = getMockedHTSTokenCurrency();
const mockedTransaction = getMockedTransaction({
mode: HEDERA_TRANSACTION_MODES.TokenAssociate,
amount: new BigNumber(0),
recipient: "0.0.1234",
maxFee: new BigNumber(1000),
properties: {
token: mockedToken,
},
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("ASSOCIATE_TOKEN");
expect(op.extra).toEqual({ associatedTokenId: mockedToken.contractAddress });
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.senders).toContain(mockedAccount.freshAddress);
expect(op.recipients).toContain("0.0.1234");
});
it("builds optimistic operation for coin", async () => {
const mockedAccount = getMockedAccount();
const mockedTransaction = getMockedTransaction({
amount: new BigNumber(123),
recipient: "0.0.5678",
maxFee: new BigNumber(1500),
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("OUT");
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.value).toEqual(new BigNumber(123));
expect(op.senders).toContain(mockedAccount.freshAddress);
expect(op.recipients).toContain("0.0.5678");
});
it("builds optimistic operation for HTS token", async () => {
const mockedTokenCurrency = getMockedHTSTokenCurrency();
const tokenAccount = getMockedTokenAccount(mockedTokenCurrency);
const parentAccount = getMockedAccount({ subAccounts: [tokenAccount] });
const mockedTransaction = getMockedTransaction({
subAccountId: tokenAccount.id,
amount: new BigNumber(123),
recipient: "0.0.9999",
maxFee: new BigNumber(2000),
});
const op = await buildOptimisticOperation({
account: parentAccount,
transaction: mockedTransaction,
});
const subOp = (op.subOperations ?? [])[0];
expect(op.type).toBe("FEES");
expect(op.value).toEqual(mockedTransaction.maxFee);
expect(op.subOperations).toHaveLength(1);
expect(subOp.type).toBe("OUT");
expect(subOp.value).toEqual(new BigNumber(123));
expect(subOp.fee).toEqual(mockedTransaction.maxFee);
expect(subOp.accountId).toBe(tokenAccount.id);
expect(subOp.recipients).toContain("0.0.9999");
});
it("builds optimistic operation for ERC20 token", async () => {
const mockedTokenCurrency = getMockedERC20TokenCurrency();
const tokenAccount = getMockedTokenAccount(mockedTokenCurrency);
const parentAccount = getMockedAccount({ subAccounts: [tokenAccount] });
const mockedTransaction = getMockedTransaction({
subAccountId: tokenAccount.id,
amount: new BigNumber(123),
recipient: "0.0.9999",
maxFee: new BigNumber(2500),
});
const op = await buildOptimisticOperation({
account: parentAccount,
transaction: mockedTransaction,
});
const subOp = (op.subOperations ?? [])[0];
expect(op.type).toBe("FEES");
expect(op.value).toEqual(mockedTransaction.maxFee);
expect(op.subOperations).toHaveLength(1);
expect(subOp.type).toBe("OUT");
expect(subOp.value).toEqual(new BigNumber(123));
expect(subOp.fee).toEqual(mockedTransaction.maxFee);
expect(subOp.accountId).toBe(tokenAccount.id);
expect(subOp.recipients).toContain("0.0.9999");
});
it("builds optimistic operation for delegate transaction", async () => {
const mockedAccount = getMockedAccount();
const stakingNodeId = 5;
const mockedTransaction = getMockedTransaction({
mode: HEDERA_TRANSACTION_MODES.Delegate,
amount: new BigNumber(0),
recipient: "",
maxFee: new BigNumber(1200),
properties: {
stakingNodeId,
},
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("DELEGATE");
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.value).toEqual(new BigNumber(0));
expect(op.senders).toContain(mockedAccount.freshAddress);
expect(op.extra).toEqual({
memo: null,
targetStakingNodeId: stakingNodeId,
previousStakingNodeId: null,
});
});
it("builds optimistic operation for redelegate transaction", async () => {
const previousNodeId = 3;
const newNodeId = 10;
const mockedAccount = getMockedAccount({
hederaResources: {
isAutoTokenAssociationEnabled: false,
maxAutomaticTokenAssociations: 0,
delegation: {
nodeId: previousNodeId,
delegated: new BigNumber(1000000),
pendingReward: new BigNumber(500),
},
},
});
const mockedTransaction = getMockedTransaction({
mode: HEDERA_TRANSACTION_MODES.Redelegate,
amount: new BigNumber(0),
recipient: "",
maxFee: new BigNumber(1300),
memo: "Redelegating to better validator",
properties: {
stakingNodeId: newNodeId,
},
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("REDELEGATE");
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.extra).toEqual({
memo: "Redelegating to better validator",
targetStakingNodeId: newNodeId,
previousStakingNodeId: previousNodeId,
});
});
it("builds optimistic operation for undelegate transaction", async () => {
const previousNodeId = 5;
const mockedAccount = getMockedAccount({
hederaResources: {
isAutoTokenAssociationEnabled: false,
maxAutomaticTokenAssociations: 0,
delegation: {
nodeId: previousNodeId,
delegated: new BigNumber(2000000),
pendingReward: new BigNumber(1000),
},
},
});
const mockedTransaction = getMockedTransaction({
mode: HEDERA_TRANSACTION_MODES.Undelegate,
amount: new BigNumber(0),
recipient: "",
maxFee: new BigNumber(1100),
properties: {
stakingNodeId: null,
},
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("UNDELEGATE");
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.value).toEqual(new BigNumber(0));
expect(op.extra).toEqual({
memo: null,
targetStakingNodeId: null,
previousStakingNodeId: previousNodeId,
});
});
it("builds optimistic operation for claim rewards transaction", async () => {
const stakingNodeId = 8;
const mockedAccount = getMockedAccount({
hederaResources: {
isAutoTokenAssociationEnabled: false,
maxAutomaticTokenAssociations: 0,
delegation: {
nodeId: stakingNodeId,
delegated: new BigNumber(5000000),
pendingReward: new BigNumber(2500),
},
},
});
const mockedTransaction = getMockedTransaction({
mode: HEDERA_TRANSACTION_MODES.ClaimRewards,
amount: new BigNumber(0),
recipient: "",
maxFee: new BigNumber(1400),
memo: "Claiming staking rewards",
});
const op = await buildOptimisticOperation({
account: mockedAccount,
transaction: mockedTransaction,
});
expect(op.type).toBe("OUT");
expect(op.fee).toEqual(mockedTransaction.maxFee);
expect(op.extra).toEqual({
memo: "Claiming staking rewards",
});
});
});