diff --git a/.changeset/warm-birds-shake.md b/.changeset/warm-birds-shake.md new file mode 100644 index 00000000000..653b3f1c221 --- /dev/null +++ b/.changeset/warm-birds-shake.md @@ -0,0 +1,7 @@ +--- +"@ledgerhq/hw-app-polkadot": minor +"@ledgerhq/coin-polkadot": minor +"@ledgerhq/live-common": minor +--- + +polkadot generic nano app support diff --git a/libs/coin-modules/coin-polkadot/package.json b/libs/coin-modules/coin-polkadot/package.json index 1658e5247fd..e04e75ca773 100644 --- a/libs/coin-modules/coin-polkadot/package.json +++ b/libs/coin-modules/coin-polkadot/package.json @@ -108,10 +108,10 @@ "@ledgerhq/logs": "workspace:^", "@ledgerhq/types-cryptoassets": "workspace:^", "@ledgerhq/types-live": "workspace:^", - "@polkadot/types": "10.9.1", - "@polkadot/types-known": "10.9.1", - "@polkadot/util": "12.5.1", - "@polkadot/util-crypto": "12.5.1", + "@polkadot/types": "11.2.1", + "@polkadot/types-known": "11.2.1", + "@polkadot/util": "12.6.2", + "@polkadot/util-crypto": "12.6.2", "bignumber.js": "^9.1.2", "expect": "^27.4.6", "invariant": "^2.2.2", diff --git a/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.test.ts b/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.test.ts index 209f8d505ad..b02c29746e3 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.test.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.test.ts @@ -2,6 +2,7 @@ import { TypeRegistry } from "@polkadot/types"; import { buildTransaction } from "./buildTransaction"; import { createFixtureAccount, createFixtureTransaction } from "../types/bridge.fixture"; import { faker } from "@faker-js/faker"; +import { getCoinConfig } from "../config"; const registry = new TypeRegistry(); @@ -25,8 +26,34 @@ jest.mock("../network", () => { }; }); +jest.mock("../config"); +const mockGetConfig = jest.mocked(getCoinConfig); + describe("buildTransaction", () => { let spyRegistry: jest.SpyInstance | undefined; + beforeAll(() => { + mockGetConfig.mockImplementation((): any => { + return { + status: { + type: "active", + }, + sidecar: { + url: "https://polkadot-sidecar.coin.ledger.com", + credentials: "", + }, + staking: { + electionStatusThreshold: 25, + }, + metadataShortener: { + url: "https://api.zondax.ch/polkadot/transaction/metadata", + }, + metadataHash: { + url: "https://api.zondax.ch/polkadot/node/metadata/hash", + }, + runtimeUpgraded: false, + }; + }); + }); afterEach(() => { mockExtrinsics.mockClear(); diff --git a/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.ts b/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.ts index 62cb262bab6..0801a74aa7d 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/buildTransaction.ts @@ -1,6 +1,7 @@ import type { PolkadotAccount, Transaction } from "../types"; import { craftTransaction, type CreateExtrinsicArg } from "../logic"; import { isFirstBond, getNonce } from "./utils"; +import { getCoinConfig } from "../config"; export const extractExtrinsicArg = ( account: PolkadotAccount, @@ -28,10 +29,12 @@ export const buildTransaction = async ( transaction: Transaction, forceLatestParams = false, ) => { + const runtimeUpgraded = getCoinConfig().runtimeUpgraded; return craftTransaction( account.freshAddress, getNonce(account), extractExtrinsicArg(account, transaction), forceLatestParams, + runtimeUpgraded, ); }; diff --git a/libs/coin-modules/coin-polkadot/src/bridge/getFeesForTransaction.test.ts b/libs/coin-modules/coin-polkadot/src/bridge/getFeesForTransaction.test.ts index 00ca74bbe9f..25c57bb137c 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/getFeesForTransaction.test.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/getFeesForTransaction.test.ts @@ -7,6 +7,7 @@ import { } from "../network/sidecar.fixture"; import { createFixtureAccount, createFixtureTransaction } from "../types/bridge.fixture"; import { createRegistryAndExtrinsics } from "../network/common"; +import { getCoinConfig } from "../config"; const mockPaymentInfo = jest.fn(); const mockRegistry = jest @@ -19,8 +20,34 @@ jest.mock("../network/sidecar", () => ({ getTransactionParams: () => mockTransactionParams(), })); +jest.mock("../config"); +const mockGetConfig = jest.mocked(getCoinConfig); + describe("getEstimatedFees", () => { const transaction = createFixtureTransaction(); + beforeAll(() => { + mockGetConfig.mockImplementation((): any => { + return { + status: { + type: "active", + }, + sidecar: { + url: "https://polkadot-sidecar.coin.ledger.com", + credentials: "", + }, + staking: { + electionStatusThreshold: 25, + }, + metadataShortener: { + url: "https://api.zondax.ch/polkadot/transaction/metadata", + }, + metadataHash: { + url: "https://api.zondax.ch/polkadot/node/metadata/hash", + }, + runtimeUpgraded: false, + }; + }); + }); beforeEach(() => { mockPaymentInfo.mockClear(); diff --git a/libs/coin-modules/coin-polkadot/src/bridge/prepareTransaction.test.ts b/libs/coin-modules/coin-polkadot/src/bridge/prepareTransaction.test.ts index 1222efdbf89..0cd738c0822 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/prepareTransaction.test.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/prepareTransaction.test.ts @@ -2,6 +2,7 @@ import BigNumber from "bignumber.js"; import { createFixtureAccount, createFixtureTransaction } from "../types/bridge.fixture"; import prepareTransaction from "./prepareTransaction"; import { faker } from "@faker-js/faker"; +import { getCoinConfig } from "../config"; const mockCraftTransaction = jest.fn(); const mockEstimateFees = jest.fn(); @@ -10,7 +11,34 @@ jest.mock("../logic", () => ({ craftTransaction: () => mockCraftTransaction(), })); +jest.mock("../config"); +const mockGetConfig = jest.mocked(getCoinConfig); + describe("prepareTransaction", () => { + beforeAll(() => { + mockGetConfig.mockImplementation((): any => { + return { + status: { + type: "active", + }, + sidecar: { + url: "https://polkadot-sidecar.coin.ledger.com", + credentials: "", + }, + staking: { + electionStatusThreshold: 25, + }, + metadataShortener: { + url: "https://api.zondax.ch/polkadot/transaction/metadata", + }, + metadataHash: { + url: "https://api.zondax.ch/polkadot/node/metadata/hash", + }, + runtimeUpgraded: false, + }; + }); + }); + afterEach(() => { mockCraftTransaction.mockClear(); mockEstimateFees.mockClear(); diff --git a/libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts b/libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts index fc1bc86a969..0855f877c6a 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/signOperation.test.ts @@ -10,6 +10,7 @@ import { fixtureTransactionParams, fixtureTxMaterialWithMetadata, } from "../network/sidecar.fixture"; +import { getCoinConfig } from "../config"; const mockPaymentInfo = jest.fn().mockResolvedValue({ weight: "WHATEVER", @@ -27,6 +28,9 @@ jest.mock("../network/sidecar", () => ({ getTransactionParams: () => mockTransactionParams(), })); +jest.mock("../config"); +const mockGetConfig = jest.mocked(getCoinConfig); + describe("signOperation", () => { // Global setup const fakeSignature = u8aConcat(new Uint8Array([1]), new Uint8Array(64).fill(0x42)); @@ -41,7 +45,29 @@ describe("signOperation", () => { fn(fakeSigner); const signOperation = buildSignOperation(signerContext); const deviceId = "dummyDeviceId"; - + beforeAll(() => { + mockGetConfig.mockImplementation((): any => { + return { + status: { + type: "active", + }, + sidecar: { + url: "https://polkadot-sidecar.coin.ledger.com", + credentials: "", + }, + staking: { + electionStatusThreshold: 25, + }, + metadataShortener: { + url: "https://api.zondax.ch/polkadot/transaction/metadata", + }, + metadataHash: { + url: "https://api.zondax.ch/polkadot/node/metadata/hash", + }, + runtimeUpgraded: false, + }; + }); + }); it("returns events in the right order", done => { // GIVEN const account = createFixtureAccount(); diff --git a/libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts b/libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts index 762c70fd784..cf85f9e04d5 100644 --- a/libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts +++ b/libs/coin-modules/coin-polkadot/src/bridge/signOperation.ts @@ -8,6 +8,8 @@ import { buildOptimisticOperation } from "./buildOptimisticOperation"; import { buildTransaction } from "./buildTransaction"; import { calculateAmount } from "./utils"; import { signExtrinsic } from "../logic"; +import polkadotAPI from "../network"; +import { getCoinConfig } from "../config"; /** * Sign Transaction with Ledger hardware @@ -19,6 +21,7 @@ export const buildSignOperation = ({ account, deviceId, transaction }) => new Observable(o => { async function main() { + const runtimeUpgraded = getCoinConfig().runtimeUpgraded; o.next({ type: "device-signature-requested", }); @@ -43,10 +46,14 @@ export const buildSignOperation = .toU8a({ method: true, }); - + let metadata = ""; + if (runtimeUpgraded) { + const payloadString = Buffer.from(payload).toString("hex"); + 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 as any), + signer.sign(account.freshAddressPath, payload, metadata), ); const signed = await signExtrinsic(unsigned, r.signature, registry); diff --git a/libs/coin-modules/coin-polkadot/src/config.ts b/libs/coin-modules/coin-polkadot/src/config.ts index 47b50a5b574..2fef9145327 100644 --- a/libs/coin-modules/coin-polkadot/src/config.ts +++ b/libs/coin-modules/coin-polkadot/src/config.ts @@ -9,6 +9,13 @@ export type PolkadotConfig = { staking?: { electionStatusThreshold: number; }; + metadataShortener: { + url: string; + }; + metadataHash: { + url: string; + }; + runtimeUpgraded: boolean; }; export type PolkadotCoinConfig = CurrencyConfig & PolkadotConfig; diff --git a/libs/coin-modules/coin-polkadot/src/logic/craftTransaction.ts b/libs/coin-modules/coin-polkadot/src/logic/craftTransaction.ts index 3aeeeee3265..db10ceb24cf 100644 --- a/libs/coin-modules/coin-polkadot/src/logic/craftTransaction.ts +++ b/libs/coin-modules/coin-polkadot/src/logic/craftTransaction.ts @@ -4,6 +4,8 @@ import type { CoreTransaction, PalletMethod, PolkadotOperationMode } from "../ty import { loadPolkadotCrypto } from "./polkadot-crypto"; import polkadotAPI from "../network"; import { getAbandonSeedAddress } from "@ledgerhq/cryptoassets/index"; +import { hexToU8a } from "@polkadot/util"; +import { CoreTransasctionInfo, TransasctionPayloadInfo } from "../types"; const EXTRINSIC_VERSION = 4; // Default values for tx parameters, if the user doesn't specify any @@ -167,6 +169,7 @@ export async function craftTransaction( nonceToUse: number, extractExtrinsicArg: CreateExtrinsicArg, forceLatestParams: boolean = false, + runtimeUpgraded: boolean = false, ): Promise { await loadPolkadotCrypto(); @@ -206,7 +209,7 @@ export async function craftTransaction( ).toHex(); const { blockHash, genesisHash } = info; - const unsigned = { + let unsigned: CoreTransasctionInfo | TransasctionPayloadInfo = { address, blockHash, blockNumber, @@ -220,6 +223,22 @@ export async function craftTransaction( transactionVersion, version: EXTRINSIC_VERSION, }; + if (runtimeUpgraded) { + const metadataHash = await polkadotAPI.metadataHash(); + unsigned = { + address, + method, + nonce: nonceToUse, + genesisHash, + era, + blockHash, + transactionVersion, + specVersion, + version: EXTRINSIC_VERSION, + mode: 1, + metadataHash: hexToU8a("01" + metadataHash), + } as TransasctionPayloadInfo; + } return { registry, diff --git a/libs/coin-modules/coin-polkadot/src/logic/signTransaction.ts b/libs/coin-modules/coin-polkadot/src/logic/signTransaction.ts index e99a7b2c3d9..9daf1b1b964 100644 --- a/libs/coin-modules/coin-polkadot/src/logic/signTransaction.ts +++ b/libs/coin-modules/coin-polkadot/src/logic/signTransaction.ts @@ -1,6 +1,6 @@ import { TypeRegistry } from "@polkadot/types"; import { u8aConcat } from "@polkadot/util"; -import { CoreTransasctionInfo } from "../types"; +import { CoreTransasctionInfo, TransasctionPayloadInfo } from "../types"; /** * Serialize a signed transaction in a format that can be submitted over the @@ -12,14 +12,19 @@ import { CoreTransasctionInfo } from "../types"; * @param registry - Registry used for constructing the payload. */ export const signExtrinsic = async ( - unsigned: CoreTransasctionInfo, + unsigned: CoreTransasctionInfo | TransasctionPayloadInfo, signature: any, registry: TypeRegistry, ): Promise => { const extrinsic = registry.createType("Extrinsic", unsigned, { version: unsigned.version, }); - extrinsic.addSignature(unsigned.address, signature, unsigned); + if (typeof signature === "string") { + extrinsic.addSignature(unsigned.address, Buffer.from(signature, "hex"), unsigned as any); + } else { + // todo: remove it after runtime upgrade + extrinsic.addSignature(unsigned.address, signature, unsigned as any); + } return extrinsic.toHex(); }; @@ -30,7 +35,7 @@ export const signExtrinsic = async ( * @param registry - Registry used for constructing the payload. */ export const fakeSignExtrinsic = async ( - unsigned: CoreTransasctionInfo, + unsigned: CoreTransasctionInfo | TransasctionPayloadInfo, registry: TypeRegistry, ): Promise => { const fakeSignature = u8aConcat(new Uint8Array([1]), new Uint8Array(64).fill(0x42)); diff --git a/libs/coin-modules/coin-polkadot/src/network/index.ts b/libs/coin-modules/coin-polkadot/src/network/index.ts index dcb2bdfe406..1495f7fdb9e 100644 --- a/libs/coin-modules/coin-polkadot/src/network/index.ts +++ b/libs/coin-modules/coin-polkadot/src/network/index.ts @@ -16,6 +16,8 @@ import { } from "./sidecar"; import BigNumber from "bignumber.js"; import { PolkadotAccount, PolkadotNomination, PolkadotUnlocking, Transaction } from "../types"; +import network from "@ledgerhq/live-network/network"; +import { getCoinConfig } from "../config"; type PolkadotAPIAccount = { blockHeight: number; @@ -67,6 +69,32 @@ const isControllerAddress = makeLRUCache( const isElectionClosed = makeLRUCache(sidecarIsElectionClosed, () => "", minutes(1)); const isNewAccount = makeLRUCache(sidecarIsNewAccount, address => address, minutes(1)); +const metadataHash = async (): Promise => { + const res: any = await network({ + method: "POST", + url: getCoinConfig().metadataHash.url, + data: { + id: "dot", + }, + }); + return res.data.metadataHash; +}; + +const shortenMetadata = async (transaction: string): Promise => { + const res: any = await network({ + method: "POST", + url: getCoinConfig().metadataShortener.url, + data: { + chain: { + id: "dot", + }, + txBlob: transaction, + }, + }); + + return res.data.txMetadata; +}; + export default { getAccount: async (address: string): Promise => sidecardGetAccount(address), getOperations: bisonGetOperations, @@ -82,6 +110,8 @@ export default { isControllerAddress, isElectionClosed, isNewAccount, + metadataHash, + shortenMetadata, submitExtrinsic: async (extrinsic: string) => sidecarSubmitExtrinsic(extrinsic), verifyValidatorAddresses: async (validators: string[]): Promise => sidecarVerifyValidatorAddresses(validators), diff --git a/libs/coin-modules/coin-polkadot/src/network/sidecar.ts b/libs/coin-modules/coin-polkadot/src/network/sidecar.ts index a22e7bfa988..63b919e6242 100644 --- a/libs/coin-modules/coin-polkadot/src/network/sidecar.ts +++ b/libs/coin-modules/coin-polkadot/src/network/sidecar.ts @@ -2,7 +2,7 @@ import { BigNumber } from "bignumber.js"; import querystring from "querystring"; import { TypeRegistry } from "@polkadot/types"; import { Extrinsics } from "@polkadot/types/metadata/decorate/types"; -import network from "@ledgerhq/live-network"; +import network from "@ledgerhq/live-network/network"; import { hours, makeLRUCache } from "@ledgerhq/live-network/cache"; import { getCoinConfig } from "../config"; import type { diff --git a/libs/coin-modules/coin-polkadot/src/network/sidecar.unit.test.ts b/libs/coin-modules/coin-polkadot/src/network/sidecar.unit.test.ts index 8ee55fd89d8..649b5c7d52a 100644 --- a/libs/coin-modules/coin-polkadot/src/network/sidecar.unit.test.ts +++ b/libs/coin-modules/coin-polkadot/src/network/sidecar.unit.test.ts @@ -17,6 +17,13 @@ describe("getAccount", () => { sidecar: { url: SIDECAR_BASE_URL_TEST, }, + metadataShortener: { + url: "", + }, + metadataHash: { + url: "", + }, + runtimeUpgraded: false, })); mockServer.listen(); @@ -88,6 +95,13 @@ describe("getRegistry", () => { sidecar: { url: SIDECAR_BASE_URL_TEST, }, + metadataShortener: { + url: "", + }, + metadataHash: { + url: "", + }, + runtimeUpgraded: false, })); mockServer.listen(); diff --git a/libs/coin-modules/coin-polkadot/src/signer/getAddress.ts b/libs/coin-modules/coin-polkadot/src/signer/getAddress.ts index 8798e4afac2..837ee0a47f5 100644 --- a/libs/coin-modules/coin-polkadot/src/signer/getAddress.ts +++ b/libs/coin-modules/coin-polkadot/src/signer/getAddress.ts @@ -2,10 +2,14 @@ import { GetAddressFn } from "@ledgerhq/coin-framework/bridge/getAddressWrapper" import { SignerContext } from "@ledgerhq/coin-framework/signer"; import { GetAddressOptions } from "@ledgerhq/coin-framework/derivation"; import type { PolkadotSigner } from "../types"; +import { getCoinConfig } from "../config"; const getAddress = (signerContext: SignerContext): GetAddressFn => { return async (deviceId: string, { path, verify }: GetAddressOptions) => { - const r = await signerContext(deviceId, signer => signer.getAddress(path, verify)); + const runtimeUpgraded = getCoinConfig().runtimeUpgraded; + const r = await signerContext(deviceId, signer => + signer.getAddress(path, 0, verify, runtimeUpgraded), + ); return { address: r.address, publicKey: r.pubKey, diff --git a/libs/coin-modules/coin-polkadot/src/test/bridgeDatasetTest.ts b/libs/coin-modules/coin-polkadot/src/test/bridgeDatasetTest.ts index 8095f7a0952..30f2a2b0951 100644 --- a/libs/coin-modules/coin-polkadot/src/test/bridgeDatasetTest.ts +++ b/libs/coin-modules/coin-polkadot/src/test/bridgeDatasetTest.ts @@ -35,15 +35,15 @@ const polkadot: CurrenciesData = { { name: "polkadot seed 1", apdus: ` - => 90010000142c00008062010080000000800000000000000000 + => 90010000182c0000806201008000000080000000000000000000000000 <= c71b1e00ca34fdd14ea065917a67168675828927e3adc3b68f444bf85b4d24be3135573461755239707652335a5765616f50516f4562616d54535557347571335072515369564a4e4e7953385868314e9000 - => 90010000142c00008062010080000000800000008000000080 + => 90010000182c0000806201008000000080000000800000008000000000 <= 845175a888f0ced372bd352d59cb51242dff8438c3dd12a703835c25bdfa3f9231337a565838337a74575939446d69757446525738374262676b627631517031666366706f4a6964626448776b3335649000 - => 90010000142c00008062010080010000800000008000000080 + => 90010000182c0000806201008001000080000000800000008000000000 <= 3a521fa830998568da9c205c987dcd157a78b2bd30ece3d1b6c32213986864ca31324b5542335272346163346469354a47707a545935474e516b44564e6b50556b636a324d4746546d7a617a4d5364739000 - => 90010000142c00008062010080020000800000008000000080 + => 90010000182c0000806201008002000080000000800000008000000000 <= 7e52138bf614dddff1116623b027ea92d6015d8fe741575b78ac7773545066bd31337264523573727657463533566b4e654a757a35576b476b4736465358515141375a423551424769673441544373399000 - => 90010000142c00008062010080030000800000008000000080 + => 90010000182c0000806201008003000080000000800000008000000000 <= dfd77108b64b8173805852f7550f1f2d6c166968d31d5c4984187c9cb1969d9331363456674b366f6f5a3466557555346946567770537558774658474c55356e5454577a4736347672447167697077689000 `, }, diff --git a/libs/coin-modules/coin-polkadot/src/types/model.ts b/libs/coin-modules/coin-polkadot/src/types/model.ts index 7e8a010f0a8..b3fa5155bab 100644 --- a/libs/coin-modules/coin-polkadot/src/types/model.ts +++ b/libs/coin-modules/coin-polkadot/src/types/model.ts @@ -27,6 +27,7 @@ export type PalletMethod = /// cf. ExtrinsicPayloadValue export type CoreTransasctionInfo = { + // before runtime upgrade address: string; blockHash: string; blockNumber: `0x${string}`; @@ -40,7 +41,23 @@ export type CoreTransasctionInfo = { transactionVersion: `0x${string}`; version: number; }; + +export type TransasctionPayloadInfo = { + // after runtime upgrade + address: string; + method: `0x${string}`; + nonce: number; + genesisHash: string; + era: `0x${string}`; + blockHash: string; + transactionVersion: `0x${string}`; + specVersion: `0x${string}`; + version: number; + mode: number; + metadataHash: Uint8Array; +}; + export type CoreTransaction = { registry: TypeRegistry; - unsigned: CoreTransasctionInfo; + unsigned: CoreTransasctionInfo | TransasctionPayloadInfo; }; diff --git a/libs/coin-modules/coin-polkadot/src/types/signer.ts b/libs/coin-modules/coin-polkadot/src/types/signer.ts index 0c43c8877d2..1db18e5029f 100644 --- a/libs/coin-modules/coin-polkadot/src/types/signer.ts +++ b/libs/coin-modules/coin-polkadot/src/types/signer.ts @@ -8,6 +8,11 @@ export type PolkadotSignature = { return_code: number; }; export interface PolkadotSigner { - getAddress(path: string, verify?: boolean): Promise; - sign(path: string, message: string): Promise; + getAddress( + path: string, + ss58prefix: number, + showAddrInDevice?: boolean, + runtimeUpgraded?: boolean, + ): Promise; + sign(path: string, message: Uint8Array, metadata: string): Promise; } diff --git a/libs/ledger-live-common/src/families/polkadot/config.ts b/libs/ledger-live-common/src/families/polkadot/config.ts index 621b264156a..9edffeccc21 100644 --- a/libs/ledger-live-common/src/families/polkadot/config.ts +++ b/libs/ledger-live-common/src/families/polkadot/config.ts @@ -1,4 +1,5 @@ import { ConfigInfo } from "@ledgerhq/live-config/LiveConfig"; +import { getEnv } from "@ledgerhq/live-env"; export const polkadotConfig: Record = { config_currency_polkadot: { @@ -7,6 +8,20 @@ export const polkadotConfig: Record = { status: { type: "active", }, + sidecar: { + url: getEnv("API_POLKADOT_SIDECAR"), + credentials: getEnv("API_POLKADOT_SIDECAR_CREDENTIALS"), + }, + staking: { + electionStatusThreshold: getEnv("POLKADOT_ELECTION_STATUS_THRESHOLD"), + }, + metadataShortener: { + url: "https://api.zondax.ch/polkadot/transaction/metadata", + }, + metadataHash: { + url: "https://api.zondax.ch/polkadot/node/metadata/hash", + }, + runtimeUpgraded: false, }, }, }; diff --git a/libs/ledger-live-common/src/families/polkadot/setup.ts b/libs/ledger-live-common/src/families/polkadot/setup.ts index 9cbc944bc25..ee34763464b 100644 --- a/libs/ledger-live-common/src/families/polkadot/setup.ts +++ b/libs/ledger-live-common/src/families/polkadot/setup.ts @@ -6,7 +6,6 @@ import { createBridges, type Transaction, } from "@ledgerhq/coin-polkadot"; -import { getEnv } from "@ledgerhq/live-env"; import Transport from "@ledgerhq/hw-transport"; import Polkadot from "@ledgerhq/hw-app-polkadot"; import type { Bridge } from "@ledgerhq/types-live"; @@ -15,24 +14,16 @@ import polkadotResolver from "@ledgerhq/coin-polkadot/signer/index"; import makeCliTools, { type CliTools } from "@ledgerhq/coin-polkadot/test/cli"; import { CreateSigner, createResolver, executeWithSigner } from "../../bridge/setup"; import { Resolver } from "../../hw/getAddress/types"; +import { getCurrencyConfiguration } from "../../config"; +import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies"; const createSigner: CreateSigner = (transport: Transport) => { return new Polkadot(transport); }; const getCurrencyConfig = (): PolkadotCoinConfig => { - return { - status: { - type: "active", - }, - sidecar: { - url: getEnv("API_POLKADOT_SIDECAR"), - credentials: getEnv("API_POLKADOT_SIDECAR_CREDENTIALS"), - }, - staking: { - electionStatusThreshold: getEnv("POLKADOT_ELECTION_STATUS_THRESHOLD"), - }, - }; + const polkadot = getCryptoCurrencyById("polkadot"); + return getCurrencyConfiguration(polkadot); }; const bridge: Bridge = createBridges( diff --git a/libs/ledgerjs/packages/hw-app-polkadot/README.md b/libs/ledgerjs/packages/hw-app-polkadot/README.md index 4c04b7c29d3..4379f595505 100644 --- a/libs/ledgerjs/packages/hw-app-polkadot/README.md +++ b/libs/ledgerjs/packages/hw-app-polkadot/README.md @@ -55,7 +55,9 @@ const polkadot = new Polkadot(transport) ##### Parameters * `path` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** -* `requireConfirmation` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** if true, user must valid if the address is correct on the device (optional, default `false`) +* `ss58prefix` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** (optional, default `0`) +* `showAddrInDevice` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** if true, user must valid if the address is correct on the device (optional, default `false`) +* `runtimeUpgraded` (optional, default `false`) Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<{pubKey: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), address: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String), return\_code: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)}>** @@ -67,5 +69,6 @@ Sign a payload * `path` **any** * `message` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** payload +* `metadata` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** Returns **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** signed payload to be broadcasted diff --git a/libs/ledgerjs/packages/hw-app-polkadot/package.json b/libs/ledgerjs/packages/hw-app-polkadot/package.json index 128421f500a..1c01ac1811a 100644 --- a/libs/ledgerjs/packages/hw-app-polkadot/package.json +++ b/libs/ledgerjs/packages/hw-app-polkadot/package.json @@ -29,6 +29,7 @@ "dependencies": { "@ledgerhq/errors": "workspace:^", "@ledgerhq/hw-transport": "workspace:^", + "@zondax/ledger-substrate": "^0.44.2", "bip32-path": "^0.4.2" }, "devDependencies": { diff --git a/libs/ledgerjs/packages/hw-app-polkadot/src/Polkadot.ts b/libs/ledgerjs/packages/hw-app-polkadot/src/Polkadot.ts index d24ce35c32d..b193111bd7e 100644 --- a/libs/ledgerjs/packages/hw-app-polkadot/src/Polkadot.ts +++ b/libs/ledgerjs/packages/hw-app-polkadot/src/Polkadot.ts @@ -17,6 +17,8 @@ import type Transport from "@ledgerhq/hw-transport"; import BIPPath from "bip32-path"; import { UserRefusedOnDevice, UserRefusedAddress, TransportError } from "@ledgerhq/errors"; +import { PolkadotGenericApp } from "@zondax/ledger-substrate"; + const CHUNK_SIZE = 250; const CLA = 0x90; const INS = { @@ -47,35 +49,40 @@ export default class Polkadot { transport.decorateAppAPIMethods(this, ["getAddress", "sign"], "DOT"); } - serializePath(path: Array): Buffer { - const buf = Buffer.alloc(20); + serializePath(path: Array, ss58?: number): Buffer { + const ss58Provided = ss58 !== undefined; + const buf = Buffer.alloc(ss58Provided ? 24 : 20); buf.writeUInt32LE(path[0], 0); buf.writeUInt32LE(path[1], 4); buf.writeUInt32LE(path[2], 8); buf.writeUInt32LE(path[3], 12); buf.writeUInt32LE(path[4], 16); + if (ss58Provided) { + buf.writeUInt32LE(ss58, 20); + } return buf; } /** * @param {string} path - * @param {boolean} requireConfirmation - if true, user must valid if the address is correct on the device + * @param {number} ss58prefix + * @param {boolean} showAddrInDevice - if true, user must valid if the address is correct on the device */ async getAddress( path: string, - requireConfirmation = false, + ss58prefix: number = 0, + showAddrInDevice = false, + runtimeUpgraded = false, ): Promise<{ pubKey: string; address: string; return_code: number; }> { + const CLA = runtimeUpgraded ? 0xf9 : 0x90; const bipPath = BIPPath.fromString(path).toPathArray(); - const bip44Path = this.serializePath(bipPath); + const bip44Path = this.serializePath(bipPath, ss58prefix); return this.transport - .send(CLA, INS.GET_ADDR_ED25519, requireConfirmation ? 1 : 0, 0, bip44Path, [ - SW_OK, - SW_CANCEL, - ]) + .send(CLA, INS.GET_ADDR_ED25519, showAddrInDevice ? 1 : 0, 0, bip44Path, [SW_OK, SW_CANCEL]) .then(response => { const errorCodeData = response.slice(-2); const returnCode = errorCodeData[0] * 256 + errorCodeData[1]; @@ -114,17 +121,30 @@ export default class Polkadot { */ async sign( path: string, - message: string, + message: Uint8Array, + metadata: string, ): Promise<{ - signature: null | string; + signature: string | null; return_code: number; }> { + if (metadata.length > 0) { + // runtimeUpgraded + const app = new PolkadotGenericApp(this.transport); + const signatureRequest = await app.signWithMetadata( + "m/" + path, + Buffer.from(message), + Buffer.from(metadata.slice(2), "hex"), + ); + return { + signature: signatureRequest.signature.toString("hex"), + return_code: SW_OK, + }; + } const bipPath = BIPPath.fromString(path).toPathArray(); const serializedPath = this.serializePath(bipPath); const chunks: Buffer[] = []; - chunks.push(serializedPath); const buffer = Buffer.from(message); - + chunks.push(serializedPath); for (let i = 0; i < buffer.length; i += CHUNK_SIZE) { let end = i + CHUNK_SIZE; @@ -158,7 +178,6 @@ export default class Polkadot { if (returnCode === SW_CANCEL) { throw new UserRefusedOnDevice(); } - if (returnCode === SW_ERROR_DATA_INVALID || returnCode === SW_ERROR_BAD_KEY_HANDLE) { const errorMessage = response.slice(0, response.length - 2).toString("ascii"); throw new TransportError(errorMessage, "Sign"); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c002e5d916c..98d196df53e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2182,17 +2182,17 @@ importers: specifier: workspace:^ version: link:../../ledgerjs/packages/types-live '@polkadot/types': - specifier: 10.9.1 - version: 10.9.1 + specifier: 11.2.1 + version: 11.2.1 '@polkadot/types-known': - specifier: 10.9.1 - version: 10.9.1 + specifier: 11.2.1 + version: 11.2.1 '@polkadot/util': - specifier: 12.5.1 - version: 12.5.1 + specifier: 12.6.2 + version: 12.6.2 '@polkadot/util-crypto': - specifier: 12.5.1 - version: 12.5.1(@polkadot/util@12.5.1) + specifier: 12.6.2 + version: 12.6.2(@polkadot/util@12.6.2) bignumber.js: specifier: ^9.1.2 version: 9.1.2 @@ -3883,6 +3883,9 @@ importers: '@ledgerhq/hw-transport': specifier: workspace:^ version: link:../hw-transport + '@zondax/ledger-substrate': + specifier: ^0.44.2 + version: 0.44.2 bip32-path: specifier: ^0.4.2 version: 0.4.2 @@ -16045,24 +16048,15 @@ packages: webpack: 5.89.0(esbuild@0.19.12) dev: true - /@polkadot/keyring@12.6.2(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1): + /@polkadot/keyring@12.6.2(@polkadot/util-crypto@12.6.2)(@polkadot/util@12.6.2): resolution: {integrity: sha512-O3Q7GVmRYm8q7HuB3S0+Yf/q/EB2egKRRU3fv9b3B7V+A52tKzA+vIwEmNVaD1g5FKW9oB97rmpggs0zaKFqHw==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': 12.6.2 '@polkadot/util-crypto': 12.6.2 dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) - tslib: 2.6.2 - dev: false - - /@polkadot/networks@12.5.1: - resolution: {integrity: sha512-PP6UUdzz6iHHZH4q96cUEhTcydHj16+61sqeaYEJSF6Q9iY+5WVWQ26+rdjmre/EBdrMQkSS/CKy73mO5z/JkQ==} - engines: {node: '>=16'} - dependencies: - '@polkadot/util': 12.5.1 - '@substrate/ss58-registry': 1.47.0 + '@polkadot/util': 12.6.2 + '@polkadot/util-crypto': 12.6.2(@polkadot/util@12.6.2) tslib: 2.6.2 dev: false @@ -16075,91 +16069,78 @@ packages: tslib: 2.6.2 dev: false - /@polkadot/types-augment@10.9.1: - resolution: {integrity: sha512-OY9/jTMFRFqYdkUnfcGwqMLC64A0Q25bjvCuVQCVjsPFKE3wl0Kt5rNT01eV2UmLXrR6fY0xWbR2w80bLA7CIQ==} - engines: {node: '>=16'} + /@polkadot/types-augment@11.2.1: + resolution: {integrity: sha512-3zBsuSKjZlMEeDVqPTkLnFvjPdyGcW3UBihzCgpTmXhLSuwTbsscMwKtKwIPkOHHQPYJYyZXTMkurMXCJOz2kA==} + engines: {node: '>=18'} dependencies: - '@polkadot/types': 10.9.1 - '@polkadot/types-codec': 10.9.1 - '@polkadot/util': 12.5.1 + '@polkadot/types': 11.2.1 + '@polkadot/types-codec': 11.2.1 + '@polkadot/util': 12.6.2 tslib: 2.6.2 dev: false - /@polkadot/types-codec@10.9.1: - resolution: {integrity: sha512-mJ5OegKGraY1FLvEa8FopRCr3pQrhDkcn5RNOjmgJQozENVeRaxhk0NwxYz7IojFvSDnKnc6lNQfKaaSe5pLHg==} - engines: {node: '>=16'} + /@polkadot/types-codec@11.2.1: + resolution: {integrity: sha512-9VRRf1g/nahAC3/VSiCSUIRL7uuup04JEZLIAG2LaDgmCBOSV9dt1Yj9114bRUrHHkeUSBmiq64+YX1hZMpQzQ==} + engines: {node: '>=18'} dependencies: - '@polkadot/util': 12.5.1 + '@polkadot/util': 12.6.2 '@polkadot/x-bigint': 12.6.2 tslib: 2.6.2 dev: false - /@polkadot/types-create@10.9.1: - resolution: {integrity: sha512-OVz50MGTTuiuVnRP/zAx4CTuLioc0hsiwNwqN2lNhmIJGtnQ4Vy/7mQRsIWehiYz6g0Vzzm5B3qWkTXO1NSN5w==} - engines: {node: '>=16'} + /@polkadot/types-create@11.2.1: + resolution: {integrity: sha512-Y0Zri7x6/rHURVNLMi6i1+rmJDLCn8OQl8BIvRmsIBkCYh2oCzy0g9aqVoCdm+QnoUU5ZNtu+U/gj1kL5ODivQ==} + engines: {node: '>=18'} dependencies: - '@polkadot/types-codec': 10.9.1 - '@polkadot/util': 12.5.1 + '@polkadot/types-codec': 11.2.1 + '@polkadot/util': 12.6.2 tslib: 2.6.2 dev: false - /@polkadot/types-known@10.9.1: - resolution: {integrity: sha512-zCMVWc4pJtkbMFPu72bD4IhvV/gkHXPX3C5uu92WdmCfnn0vEIEsMKWlVXVVvQQZKAqvs/awpqIfrUtEViOGEA==} - engines: {node: '>=16'} + /@polkadot/types-known@11.2.1: + resolution: {integrity: sha512-dnbmVKagVI6ARuZaGMGc67HPeHGrR7/lcwfS7jGzEmRcoQk7p/UQjWfOk/LG9NzvQkmRVbE0Gqskn4VorqnTbA==} + engines: {node: '>=18'} dependencies: '@polkadot/networks': 12.6.2 - '@polkadot/types': 10.9.1 - '@polkadot/types-codec': 10.9.1 - '@polkadot/types-create': 10.9.1 - '@polkadot/util': 12.5.1 + '@polkadot/types': 11.2.1 + '@polkadot/types-codec': 11.2.1 + '@polkadot/types-create': 11.2.1 + '@polkadot/util': 12.6.2 tslib: 2.6.2 dev: false - /@polkadot/types@10.9.1: - resolution: {integrity: sha512-AG33i2ZGGfq7u+5rkAdGrXAQHHl844/Yv+junH5ZzX69xiCoWO1bH/yzDUNBdpki2GlACWvF9nLYh3F2tVF93w==} - engines: {node: '>=16'} + /@polkadot/types@11.2.1: + resolution: {integrity: sha512-NVPhO/eFPkL8arWk4xVbsJzRdGfue3gJK+A2iYzOfCr9rDHEj99B+E2Z0Or6zDN6n+thgQYwsr19rKgXvAc18Q==} + engines: {node: '>=18'} dependencies: - '@polkadot/keyring': 12.6.2(@polkadot/util-crypto@12.5.1)(@polkadot/util@12.5.1) - '@polkadot/types-augment': 10.9.1 - '@polkadot/types-codec': 10.9.1 - '@polkadot/types-create': 10.9.1 - '@polkadot/util': 12.5.1 - '@polkadot/util-crypto': 12.5.1(@polkadot/util@12.5.1) + '@polkadot/keyring': 12.6.2(@polkadot/util-crypto@12.6.2)(@polkadot/util@12.6.2) + '@polkadot/types-augment': 11.2.1 + '@polkadot/types-codec': 11.2.1 + '@polkadot/types-create': 11.2.1 + '@polkadot/util': 12.6.2 + '@polkadot/util-crypto': 12.6.2(@polkadot/util@12.6.2) rxjs: 7.8.1 tslib: 2.6.2 dev: false - /@polkadot/util-crypto@12.5.1(@polkadot/util@12.5.1): - resolution: {integrity: sha512-Y8ORbMcsM/VOqSG3DgqutRGQ8XXK+X9M3C8oOEI2Tji65ZsXbh9Yh+ryPLM0oBp/9vqOXjkLgZJbbVuQceOw0A==} - engines: {node: '>=16'} + /@polkadot/util-crypto@12.6.2(@polkadot/util@12.6.2): + resolution: {integrity: sha512-FEWI/dJ7wDMNN1WOzZAjQoIcCP/3vz3wvAp5QQm+lOrzOLj0iDmaIGIcBkz8HVm3ErfSe/uKP0KS4jgV/ib+Mg==} + engines: {node: '>=18'} peerDependencies: - '@polkadot/util': 12.5.1 + '@polkadot/util': 12.6.2 dependencies: '@noble/curves': 1.4.0 '@noble/hashes': 1.4.0 - '@polkadot/networks': 12.5.1 - '@polkadot/util': 12.5.1 - '@polkadot/wasm-crypto': 7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1) - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/x-bigint': 12.5.1 - '@polkadot/x-randomvalues': 12.5.1(@polkadot/util@12.5.1)(@polkadot/wasm-util@7.3.2) + '@polkadot/networks': 12.6.2 + '@polkadot/util': 12.6.2 + '@polkadot/wasm-crypto': 7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2) + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/x-bigint': 12.6.2 + '@polkadot/x-randomvalues': 12.6.2(@polkadot/util@12.6.2)(@polkadot/wasm-util@7.3.2) '@scure/base': 1.1.6 tslib: 2.6.2 dev: false - /@polkadot/util@12.5.1: - resolution: {integrity: sha512-fDBZL7D4/baMG09Qowseo884m3QBzErGkRWNBId1UjWR99kyex+cIY9fOSzmuQxo6nLdJlLHw1Nz2caN3+Bq0A==} - engines: {node: '>=16'} - dependencies: - '@polkadot/x-bigint': 12.5.1 - '@polkadot/x-global': 12.5.1 - '@polkadot/x-textdecoder': 12.5.1 - '@polkadot/x-textencoder': 12.5.1 - '@types/bn.js': 5.1.5 - bn.js: 5.2.1 - tslib: 2.6.2 - dev: false - /@polkadot/util@12.6.2: resolution: {integrity: sha512-l8TubR7CLEY47240uki0TQzFvtnxFIO7uI/0GoWzpYD/O62EIAMRsuY01N4DuwgKq2ZWD59WhzsLYmA5K6ksdw==} engines: {node: '>=18'} @@ -16173,88 +16154,80 @@ packages: tslib: 2.6.2 dev: false - /@polkadot/wasm-bridge@7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1): + /@polkadot/wasm-bridge@7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2): resolution: {integrity: sha512-AJEXChcf/nKXd5Q/YLEV5dXQMle3UNT7jcXYmIffZAo/KI394a+/24PaISyQjoNC0fkzS1Q8T5pnGGHmXiVz2g==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/x-randomvalues': 12.5.1(@polkadot/util@12.5.1)(@polkadot/wasm-util@7.3.2) + '@polkadot/util': 12.6.2 + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/x-randomvalues': 12.6.2(@polkadot/util@12.6.2)(@polkadot/wasm-util@7.3.2) tslib: 2.6.2 dev: false - /@polkadot/wasm-crypto-asmjs@7.3.2(@polkadot/util@12.5.1): + /@polkadot/wasm-crypto-asmjs@7.3.2(@polkadot/util@12.6.2): resolution: {integrity: sha512-QP5eiUqUFur/2UoF2KKKYJcesc71fXhQFLT3D4ZjG28Mfk2ZPI0QNRUfpcxVQmIUpV5USHg4geCBNuCYsMm20Q==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' dependencies: - '@polkadot/util': 12.5.1 + '@polkadot/util': 12.6.2 tslib: 2.6.2 dev: false - /@polkadot/wasm-crypto-init@7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1): + /@polkadot/wasm-crypto-init@7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2): resolution: {integrity: sha512-FPq73zGmvZtnuJaFV44brze3Lkrki3b4PebxCy9Fplw8nTmisKo9Xxtfew08r0njyYh+uiJRAxPCXadkC9sc8g==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/wasm-bridge': 7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1) - '@polkadot/wasm-crypto-asmjs': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/wasm-crypto-wasm': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/x-randomvalues': 12.5.1(@polkadot/util@12.5.1)(@polkadot/wasm-util@7.3.2) + '@polkadot/util': 12.6.2 + '@polkadot/wasm-bridge': 7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2) + '@polkadot/wasm-crypto-asmjs': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/wasm-crypto-wasm': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/x-randomvalues': 12.6.2(@polkadot/util@12.6.2)(@polkadot/wasm-util@7.3.2) tslib: 2.6.2 dev: false - /@polkadot/wasm-crypto-wasm@7.3.2(@polkadot/util@12.5.1): + /@polkadot/wasm-crypto-wasm@7.3.2(@polkadot/util@12.6.2): resolution: {integrity: sha512-15wd0EMv9IXs5Abp1ZKpKKAVyZPhATIAHfKsyoWCEFDLSOA0/K0QGOxzrAlsrdUkiKZOq7uzSIgIDgW8okx2Mw==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) + '@polkadot/util': 12.6.2 + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) tslib: 2.6.2 dev: false - /@polkadot/wasm-crypto@7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1): + /@polkadot/wasm-crypto@7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2): resolution: {integrity: sha512-+neIDLSJ6jjVXsjyZ5oLSv16oIpwp+PxFqTUaZdZDoA2EyFRQB8pP7+qLsMNk+WJuhuJ4qXil/7XiOnZYZ+wxw==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' '@polkadot/x-randomvalues': '*' dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/wasm-bridge': 7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1) - '@polkadot/wasm-crypto-asmjs': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/wasm-crypto-init': 7.3.2(@polkadot/util@12.5.1)(@polkadot/x-randomvalues@12.5.1) - '@polkadot/wasm-crypto-wasm': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/x-randomvalues': 12.5.1(@polkadot/util@12.5.1)(@polkadot/wasm-util@7.3.2) + '@polkadot/util': 12.6.2 + '@polkadot/wasm-bridge': 7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2) + '@polkadot/wasm-crypto-asmjs': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/wasm-crypto-init': 7.3.2(@polkadot/util@12.6.2)(@polkadot/x-randomvalues@12.6.2) + '@polkadot/wasm-crypto-wasm': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/x-randomvalues': 12.6.2(@polkadot/util@12.6.2)(@polkadot/wasm-util@7.3.2) tslib: 2.6.2 dev: false - /@polkadot/wasm-util@7.3.2(@polkadot/util@12.5.1): + /@polkadot/wasm-util@7.3.2(@polkadot/util@12.6.2): resolution: {integrity: sha512-bmD+Dxo1lTZyZNxbyPE380wd82QsX+43mgCm40boyKrRppXEyQmWT98v/Poc7chLuskYb6X8IQ6lvvK2bGR4Tg==} engines: {node: '>=18'} peerDependencies: '@polkadot/util': '*' dependencies: - '@polkadot/util': 12.5.1 - tslib: 2.6.2 - dev: false - - /@polkadot/x-bigint@12.5.1: - resolution: {integrity: sha512-Fw39eoN9v0sqxSzfSC5awaDVdzojIiE7d1hRSQgVSrES+8whWvtbYMR0qwbVhTuW7DvogHmye41P9xKMlXZysg==} - engines: {node: '>=16'} - dependencies: - '@polkadot/x-global': 12.5.1 + '@polkadot/util': 12.6.2 tslib: 2.6.2 dev: false @@ -16266,13 +16239,6 @@ packages: tslib: 2.6.2 dev: false - /@polkadot/x-global@12.5.1: - resolution: {integrity: sha512-6K0YtWEg0eXInDOihU5aSzeb1t9TiDdX9ZuRly+58ALSqw5kPZYmQLbzE1d8HWzyXRXK+YH65GtLzfMGqfYHmw==} - engines: {node: '>=16'} - dependencies: - tslib: 2.6.2 - dev: false - /@polkadot/x-global@12.6.2: resolution: {integrity: sha512-a8d6m+PW98jmsYDtAWp88qS4dl8DyqUBsd0S+WgyfSMtpEXu6v9nXDgPZgwF5xdDvXhm+P0ZfVkVTnIGrScb5g==} engines: {node: '>=18'} @@ -16280,24 +16246,16 @@ packages: tslib: 2.6.2 dev: false - /@polkadot/x-randomvalues@12.5.1(@polkadot/util@12.5.1)(@polkadot/wasm-util@7.3.2): - resolution: {integrity: sha512-UsMb1d+77EPNjW78BpHjZLIm4TaIpfqq89OhZP/6gDIoS2V9iE/AK3jOWKm1G7Y2F8XIoX1qzQpuMakjfagFoQ==} - engines: {node: '>=16'} + /@polkadot/x-randomvalues@12.6.2(@polkadot/util@12.6.2)(@polkadot/wasm-util@7.3.2): + resolution: {integrity: sha512-Vr8uG7rH2IcNJwtyf5ebdODMcr0XjoCpUbI91Zv6AlKVYOGKZlKLYJHIwpTaKKB+7KPWyQrk4Mlym/rS7v9feg==} + engines: {node: '>=18'} peerDependencies: - '@polkadot/util': 12.5.1 + '@polkadot/util': 12.6.2 '@polkadot/wasm-util': '*' dependencies: - '@polkadot/util': 12.5.1 - '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.5.1) - '@polkadot/x-global': 12.5.1 - tslib: 2.6.2 - dev: false - - /@polkadot/x-textdecoder@12.5.1: - resolution: {integrity: sha512-j2YZGWfwhMC8nHW3BXq10fAPY02ObLL/qoTjCMJ1Cmc/OGq18Ep7k9cXXbjFAq3wf3tUUewt/u/hStKCk3IvfQ==} - engines: {node: '>=16'} - dependencies: - '@polkadot/x-global': 12.5.1 + '@polkadot/util': 12.6.2 + '@polkadot/wasm-util': 7.3.2(@polkadot/util@12.6.2) + '@polkadot/x-global': 12.6.2 tslib: 2.6.2 dev: false @@ -16309,14 +16267,6 @@ packages: tslib: 2.6.2 dev: false - /@polkadot/x-textencoder@12.5.1: - resolution: {integrity: sha512-1JNNpOGb4wD+c7zFuOqjibl49LPnHNr4rj4s3WflLUIZvOMY6euoDuN3ISjQSHCLlVSoH0sOCWA3qXZU4bCTDQ==} - engines: {node: '>=16'} - dependencies: - '@polkadot/x-global': 12.5.1 - tslib: 2.6.2 - dev: false - /@polkadot/x-textencoder@12.6.2: resolution: {integrity: sha512-4N+3UVCpI489tUJ6cv3uf0PjOHvgGp9Dl+SZRLgFGt9mvxnvpW/7+XBADRMtlG4xi5gaRK7bgl5bmY6OMDsNdw==} engines: {node: '>=18'} @@ -25165,7 +25115,7 @@ packages: resolution: {integrity: sha512-IyMsxyjkJK8YWq566KyuFuh/PUiLzQ02RbUO5qa+vEQb6zIAR9MzFwN7wBmBy7wmKkjligcdNDMG5EaBRH8FxQ==} engines: {node: '>=16.0.0'} dependencies: - '@noble/hashes': 1.3.3 + '@noble/hashes': 1.4.0 eventemitter3: 5.0.1 ws: 8.16.0 transitivePeerDependencies: @@ -25273,6 +25223,12 @@ packages: '@ledgerhq/hw-transport': 6.28.1 dev: false + /@zondax/ledger-js@0.8.2: + resolution: {integrity: sha512-U/lzNzcJwfYGhhpwUviazihXzIv8w3rM31HbgKWOwF/xVS4/hHSLCGpONEGVwtgYUNDF7L0YfSy95/0H+tGtFA==} + dependencies: + '@ledgerhq/hw-transport': 6.30.6 + dev: false + /@zondax/ledger-stacks@1.0.4: resolution: {integrity: sha512-R8CB0CZ2poTzpcG0jhzzXZvXF7axIsmZFhp06aHCUjgz+1df63YbC4tUzyzmseekwqNWnaebWFejQKJ99WiHZA==} dependencies: @@ -25284,6 +25240,14 @@ packages: - encoding dev: false + /@zondax/ledger-substrate@0.44.2: + resolution: {integrity: sha512-9KSagJVEh2YNtkKsVLZdHM++AGYGRDSdGV2H46sy4qhjGh/p/R4h5amM4OzlQhMTdxc9EW13lHZwoucliosbxw==} + dependencies: + '@ledgerhq/hw-transport': 6.30.6 + '@zondax/ledger-js': 0.8.2 + axios: 1.6.8 + dev: false + /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -27614,7 +27578,7 @@ packages: resolution: {integrity: sha512-rpwfAcS/CMqo0oCqDf3r9eeLgScRE3l/xHDCXhM3UyrfvIn7PrLq63uHh7yYbv8NzaZn5MVsVhIRpQ+5GZ5HyA==} engines: {node: '>=8'} dependencies: - '@noble/hashes': 1.3.2 + '@noble/hashes': 1.4.0 base-x: 4.0.0 dev: false