Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LIVE-13040: polkadot code cleanup #7812

Merged
merged 10 commits into from
Sep 30, 2024
7 changes: 7 additions & 0 deletions .changeset/tasty-brooms-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ledgerhq/hw-app-polkadot": minor
"@ledgerhq/coin-polkadot": minor
"@ledgerhq/live-common": minor
---

polkadot code cleanup
12 changes: 6 additions & 6 deletions libs/coin-modules/coin-polkadot/src/api/index.integ.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ describe("Polkadot Api", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
});
});

Expand All @@ -35,7 +34,8 @@ describe("Polkadot Api", () => {
const result = await module.estimateFees(address, amount);

// Then
expect(result).toEqual(BigInt(154107779));
expect(result).toBeGreaterThanOrEqual(BigInt(100000000));
expect(result).toBeLessThanOrEqual(BigInt(200000000));
});
});

Expand Down Expand Up @@ -74,7 +74,7 @@ describe("Polkadot Api", () => {

// Then
expect(result).toBeGreaterThan(0);
});
}, 10000);
});

describe("craftTransaction", () => {
Expand All @@ -89,7 +89,7 @@ describe("Polkadot Api", () => {

// Then
expect(result).toEqual(
"6c0053ddb3b3a89ed5c8d8326066032beac6de225c9e010300000a0000a31e81ac3425310e3274a4698a793b2839dc0afa00",
"0x9404050300f578e65647d6c76b4d05a74e6c2d33d87f32d8d16959400b38ab97d758eb061928",
);
});
});
Expand Down
2 changes: 1 addition & 1 deletion libs/coin-modules/coin-polkadot/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ async function craft(
): Promise<string> {
const extrinsicArg = defaultExtrinsicArg(transaction.amount, transaction.recipient);
//TODO: Retrieve correctly the nonce via a call to the node `await api.rpc.system.accountNextIndex(address)`
const nonce = -1;
const nonce = 0;
const tx = await craftTransaction(address, nonce, extrinsicArg);
const extrinsic = tx.registry.createType("Extrinsic", tx.unsigned, {
version: tx.unsigned.version,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ jest.mock("../network", () => {
extrinsics: mockExtrinsics(),
}),
getTransactionParams: () => mockGetTransactionParams(),
metadataHash: () => "0x12345678",
};
});

Expand All @@ -45,12 +46,11 @@ describe("buildTransaction", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down Expand Up @@ -89,16 +89,14 @@ describe("buildTransaction", () => {
const result = await buildTransaction(account, transaction);

// THEN
expect(spyRegistry).toHaveBeenCalledTimes(6);
expect(spyRegistry).toHaveBeenCalledWith("BlockNumber", 12);
expect(spyRegistry).toHaveBeenCalledTimes(3);
expect(spyRegistry).toHaveBeenCalledWith("ExtrinsicEra", {
current: 12,
period: 64,
});
expect(spyRegistry).toHaveBeenCalledWith("u32", 42);
expect(spyRegistry).toHaveBeenCalledWith("Compact<Balance>", 0);
expect(spyRegistry).toHaveBeenCalledWith("u32", 22);
expect(mockCodec).toHaveBeenCalledTimes(6);
expect(mockCodec).toHaveBeenCalledTimes(3);
expect(mockExtrinsics).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive.mock.calls[0][0]).toEqual("WHATEVER");
Expand All @@ -111,25 +109,16 @@ describe("buildTransaction", () => {
blockHash: "0xb10c4a54",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
signedExtensions: [
"CheckVersion",
"CheckGenesis",
"CheckEra",
"CheckNonce",
"CheckWeight",
"ChargeTransactionPayment",
"CheckBlockGasLimit",
],
blockNumber: "HexCodec 4 BlockNumber",
era: "HexCodec 4 ExtrinsicEra",
nonce: "HexCodec 4 Compact<Index>",
nonce: expect.any(Number),
mode: 1,
metadataHash: new Uint8Array([1, 0, 18, 52, 86, 120]),
specVersion: "HexCodec 4 u32",
tip: "HexCodec 4 Compact<Balance>",
transactionVersion: "HexCodec 4 u32",
version: 4,
},
};
expect(result).toEqual(expectedResult);
expect(result.unsigned).toEqual(expectedResult.unsigned);
});

it('returns an unsigned with all validators when transaction has mode "nominate"', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { PolkadotAccount, Transaction } from "../types";
import { craftTransaction, type CreateExtrinsicArg } from "../logic";
import { isFirstBond, getNonce } from "./utils";
import coinConfig from "../config";

export const extractExtrinsicArg = (
account: PolkadotAccount,
Expand Down Expand Up @@ -29,12 +28,10 @@ export const buildTransaction = async (
transaction: Transaction,
forceLatestParams = false,
) => {
const runtimeUpgraded = coinConfig.getCoinConfig().runtimeUpgraded;
return craftTransaction(
account.freshAddress,
getNonce(account),
extractExtrinsicArg(account, transaction),
forceLatestParams,
runtimeUpgraded,
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@ describe("getEstimatedFees", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ describe("prepareTransaction", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
33 changes: 16 additions & 17 deletions libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,34 @@ import type { PolkadotOperationMode, PolkadotSigner, PolkadotOperationExtra } fr
import { createFixtureAccount, createFixtureTransaction } from "../types/bridge.fixture";
import buildSignOperation from "./signOperation";
import { createRegistryAndExtrinsics } from "../network/common";

import {
fixtureChainSpec,
fixtureTransactionParams,
fixtureTxMaterialWithMetadata,
} from "../network/sidecar.fixture";
import coinConfig from "../config";

jest.mock("../config");
const mockGetConfig = jest.mocked(coinConfig.getCoinConfig);
const mockRegistry = jest
.fn()
.mockResolvedValue(createRegistryAndExtrinsics(fixtureTxMaterialWithMetadata, fixtureChainSpec));
const mockTransactionParams = jest.fn().mockResolvedValue(fixtureTransactionParams);
const mockPaymentInfo = jest.fn().mockResolvedValue({
weight: "WHATEVER",
class: "WHATEVER",
partialFee: "155099814",
});
const mockRegistry = jest
.fn()
.mockResolvedValue(createRegistryAndExtrinsics(fixtureTxMaterialWithMetadata, fixtureChainSpec));
const mockTransactionParams = jest.fn().mockResolvedValue(fixtureTransactionParams);

jest.mock("../network/sidecar", () => ({
getRegistry: () => mockRegistry(),
paymentInfo: (args: any) => mockPaymentInfo(args),
getTransactionParams: () => mockTransactionParams(),
}));

jest.mock("../config");
const mockGetConfig = jest.mocked(coinConfig.getCoinConfig);

describe("signOperation", () => {
// Global setup
jest.setTimeout(20000);
jest.mock("../network/sidecar", () => ({
getRegistry: () => mockRegistry(),
paymentInfo: (args: any) => mockPaymentInfo(args),
getTransactionParams: () => mockTransactionParams(),
fetchTransactionMaterial: () => fixtureTxMaterialWithMetadata,
}));
const fakeSignature = u8aConcat(new Uint8Array([1]), new Uint8Array(64).fill(0x42));
const fakeSigner = {
getAddress: jest.fn(),
Expand All @@ -59,12 +59,11 @@ describe("signOperation", () => {
electionStatusThreshold: 25,
},
metadataShortener: {
url: "https://api.zondax.ch/polkadot/transaction/metadata",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/transaction/metadata",
},
metadataHash: {
url: "https://api.zondax.ch/polkadot/node/metadata/hash",
url: "https://polkadot-metadata-shortener.api.live.ledger.com/node/metadata/hash",
},
runtimeUpgraded: false,
};
});
});
Expand Down
10 changes: 2 additions & 8 deletions libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { buildTransaction } from "./buildTransaction";
import { calculateAmount } from "./utils";
import { signExtrinsic } from "../logic";
import polkadotAPI from "../network";
import coinConfig from "../config";

/**
* Sign Transaction with Ledger hardware
Expand All @@ -21,7 +20,6 @@ export const buildSignOperation =
({ account, deviceId, transaction }) =>
new Observable(o => {
async function main() {
const runtimeUpgraded = coinConfig.getCoinConfig().runtimeUpgraded;
o.next({
type: "device-signature-requested",
});
Expand All @@ -46,13 +44,9 @@ export const buildSignOperation =
.toU8a({
method: true,
});
let metadata = "";
if (runtimeUpgraded) {
const payloadString = Buffer.from(payload).toString("hex");
metadata = await polkadotAPI.shortenMetadata(payloadString);
}
const payloadString = Buffer.from(payload).toString("hex");
const metadata = await polkadotAPI.shortenMetadata(payloadString);
const r = await signerContext(deviceId, signer =>
// FIXME: the type of payload Uint8Array is not compatible with the signature of sign which accept a string
signer.sign(account.freshAddressPath, payload, metadata),
);

Expand Down
1 change: 0 additions & 1 deletion libs/coin-modules/coin-polkadot/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export type PolkadotConfig = {
metadataHash: {
url: string;
};
runtimeUpgraded: boolean;
};

export type PolkadotCoinConfig = CurrencyConfig & PolkadotConfig;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jest.mock("../network", () => {
extrinsics: mockExtrinsics(),
}),
getTransactionParams: () => mockGetTransactionParams(),
metadataHash: () => "0x12345678",
};
});

Expand Down Expand Up @@ -60,48 +61,35 @@ describe("craftTransaction", () => {
});

// WHEN
const result = await craftTransaction(address, 0, defaultExtrinsicArg(amount, recipient));
const result = (await craftTransaction(address, 0, defaultExtrinsicArg(amount, recipient)))
.unsigned;

// THEN
expect(spyRegistry).toHaveBeenCalledTimes(6);
expect(spyRegistry).toHaveBeenCalledWith("BlockNumber", 12);
expect(spyRegistry).toHaveBeenCalledTimes(3);
expect(spyRegistry).toHaveBeenCalledWith("ExtrinsicEra", {
current: 12,
period: 64,
});
expect(spyRegistry).toHaveBeenCalledWith("u32", 42);
expect(spyRegistry).toHaveBeenCalledWith("Compact<Balance>", 0);
expect(spyRegistry).toHaveBeenCalledWith("u32", 22);
expect(mockCodec).toHaveBeenCalledTimes(6);
expect(mockCodec).toHaveBeenCalledTimes(3);
expect(mockExtrinsics).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive).toHaveBeenCalledTimes(1);
expect(mockTransferKeepAlive.mock.lastCall[0]).toEqual(recipient);
expect(mockTransferKeepAlive.mock.lastCall[1]).toEqual(amount.toString());

const expectedResult = {
registry: registry,
unsigned: {
address,
blockHash: "0xb10c4a54",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
signedExtensions: [
"CheckVersion",
"CheckGenesis",
"CheckEra",
"CheckNonce",
"CheckWeight",
"ChargeTransactionPayment",
"CheckBlockGasLimit",
],
blockNumber: "HexCodec 4 BlockNumber",
era: "HexCodec 4 ExtrinsicEra",
nonce: "HexCodec 4 Compact<Index>",
specVersion: "HexCodec 4 u32",
tip: "HexCodec 4 Compact<Balance>",
transactionVersion: "HexCodec 4 u32",
version: 4,
},
address: "5D4yQHKfqCQYThhHmTfN1JEDi47uyDJc1xg9eZfAG1R7FC7J",
blockHash: "0xb10c4a54",
era: "HexCodec 4 ExtrinsicEra",
genesisHash: "0x83835154a54",
method: expectExtrinsicMethodHex,
nonce: 0,
transactionVersion: "HexCodec 4 u32",
specVersion: "HexCodec 4 u32",
version: 4,
metadataHash: new Uint8Array([1, 0, 18, 52, 86, 120]),
mode: 1,
};
expect(result).toEqual(expectedResult);
});
Expand Down
Loading
Loading