diff --git a/libs/coin-framework/src/derivation.ts b/libs/coin-framework/src/derivation.ts index 20d7a4f27ba5..bc2fcb9f60fa 100644 --- a/libs/coin-framework/src/derivation.ts +++ b/libs/coin-framework/src/derivation.ts @@ -151,7 +151,10 @@ const modes: Readonly> = Object.freeze({ solanaSub: { overridesDerivation: "44'/501'/'", }, - hederaBip44: { + hederaBip44Ed25519: { + overridesDerivation: "44/3030", + }, + hederaBip44Ecdsa: { overridesDerivation: "44/3030", }, cardano: { @@ -191,7 +194,7 @@ const legacyDerivations: Partial> tezos: ["galleonL", "tezboxL", "tezosbip44h", "tezbox"], stellar: ["sep5"], polkadot: ["polkadotbip44"], - hedera: ["hederaBip44"], + hedera: ["hederaBip44Ed25519", "hederaBip44Ecdsa"], filecoin: ["glifLegacy", "filecoinBIP44", "glif"], internet_computer: ["internet_computer"], casper: ["casper_wallet"], diff --git a/libs/coin-modules/coin-hedera/src/api/mirror.ts b/libs/coin-modules/coin-hedera/src/api/mirror.ts index 4f4223190653..7ec2c8a85078 100644 --- a/libs/coin-modules/coin-hedera/src/api/mirror.ts +++ b/libs/coin-modules/coin-hedera/src/api/mirror.ts @@ -19,6 +19,7 @@ const fetch = (path: string) => { export interface Account { accountId: AccountId; balance: BigNumber; + keyType: string; } export async function getAccountsForPublicKey(publicKey: string): Promise { @@ -38,12 +39,25 @@ export async function getAccountsForPublicKey(publicKey: string): Promise { + let r; + try { + r = await fetch(`/api/v1/accounts/${accountId}`); + } catch (e: any) { + if (e.name === "LedgerAPI4xx") return ""; + throw e; + } + + return r.data.key._type; +} + interface HederaMirrorTransaction { transfers: HederaMirrorTransfer[]; charged_tx_fee: string; diff --git a/libs/coin-modules/coin-hedera/src/bridge/signOperation.ts b/libs/coin-modules/coin-hedera/src/bridge/signOperation.ts index 954ce7dd2cac..73a1d3f43d13 100644 --- a/libs/coin-modules/coin-hedera/src/bridge/signOperation.ts +++ b/libs/coin-modules/coin-hedera/src/bridge/signOperation.ts @@ -5,6 +5,7 @@ import { buildOptimisticOperation } from "./buildOptimisticOperation"; import { buildUnsignedTransaction } from "../api/network"; import { SignerContext } from "@ledgerhq/coin-framework/signer"; import { Transaction, HederaSigner } from "../types"; +import { getKeyTypeForAccount } from "../api/mirror"; export const buildSignOperation = ( @@ -25,9 +26,11 @@ export const buildSignOperation = const accountPublicKey = PublicKey.fromString(account.seedIdentifier); + const keyType = await getKeyTypeForAccount(account.freshAddress); + const res = await signerContext(deviceId, async signer => { await hederaTransaction.signWith(accountPublicKey, async bodyBytes => { - return await signer.signTransaction(bodyBytes); + return await signer.signTransaction(bodyBytes, keyType !== "ED25519"); }); return hederaTransaction.toBytes(); }); diff --git a/libs/coin-modules/coin-hedera/src/bridge/synchronisation.ts b/libs/coin-modules/coin-hedera/src/bridge/synchronisation.ts index 2f958db4b66e..af1a8ed5539a 100644 --- a/libs/coin-modules/coin-hedera/src/bridge/synchronisation.ts +++ b/libs/coin-modules/coin-hedera/src/bridge/synchronisation.ts @@ -60,6 +60,7 @@ export const getAccountShape: GetAccountShape = async ( }; export const buildIterateResult: IterateResultBuilder = async ({ result: rootResult }) => { + console.log(rootResult.publicKey); const accounts = await getAccountsForPublicKey(rootResult.publicKey); const addresses = accounts.map(a => a.accountId.toString()); diff --git a/libs/coin-modules/coin-hedera/src/signer/getAddress.ts b/libs/coin-modules/coin-hedera/src/signer/getAddress.ts index 6cf277f64ddf..4772529ff725 100644 --- a/libs/coin-modules/coin-hedera/src/signer/getAddress.ts +++ b/libs/coin-modules/coin-hedera/src/signer/getAddress.ts @@ -4,8 +4,14 @@ import { SignerContext } from "@ledgerhq/coin-framework/signer"; import { GetAddressOptions } from "@ledgerhq/coin-framework/derivation"; const resolver = (signerContext: SignerContext): GetAddressFn => { - return async (deviceId: string, { path }: GetAddressOptions) => { - const publicKey = await signerContext(deviceId, signer => signer.getPublicKey(path)); + return async (deviceId: string, { path, derivationMode }: GetAddressOptions) => { + let publicKey = ""; + console.log(derivationMode); + if (derivationMode == "hederaBip44Ecdsa") { + publicKey = await signerContext(deviceId, signer => signer.getPublicKey(path, true)); + console.log(publicKey); + } + publicKey = await signerContext(deviceId, signer => signer.getPublicKey(path)); return { path, diff --git a/libs/coin-modules/coin-hedera/src/test/bridgeDatasetTest.ts b/libs/coin-modules/coin-hedera/src/test/bridgeDatasetTest.ts index 136c0eac428b..09e609a3fb49 100644 --- a/libs/coin-modules/coin-hedera/src/test/bridgeDatasetTest.ts +++ b/libs/coin-modules/coin-hedera/src/test/bridgeDatasetTest.ts @@ -27,7 +27,7 @@ export const hedera: CurrenciesData = { id: `js:2:hedera:0.0.751515:`, seedIdentifier: "", name: "Hedera 1", - derivationMode: "hederaBip44", + derivationMode: "hederaBip44Ed25519", index: 0, freshAddress: "0.0.751515", freshAddressPath: "44/3030/0/0/0", diff --git a/libs/coin-modules/coin-hedera/src/types/signer.ts b/libs/coin-modules/coin-hedera/src/types/signer.ts index a8e7c6611f06..73f7771011b8 100644 --- a/libs/coin-modules/coin-hedera/src/types/signer.ts +++ b/libs/coin-modules/coin-hedera/src/types/signer.ts @@ -1,7 +1,7 @@ export type HederaSignature = Uint8Array | undefined; // NOTE: check if undefined is possible export interface HederaSigner { - getPublicKey(path: string): Promise; - signTransaction(transaction: Uint8Array): Promise; + getPublicKey(path: string, ecdsa?: boolean): Promise; + signTransaction(transaction: Uint8Array, ecdsa?: boolean): Promise; } export type HederaSignatureSdk = Uint8Array; diff --git a/libs/ledgerjs/packages/hw-app-hedera/src/Hedera.ts b/libs/ledgerjs/packages/hw-app-hedera/src/Hedera.ts index a065c5b9e31e..3d2bcb5f4fd3 100644 --- a/libs/ledgerjs/packages/hw-app-hedera/src/Hedera.ts +++ b/libs/ledgerjs/packages/hw-app-hedera/src/Hedera.ts @@ -33,15 +33,26 @@ export default class Hedera { * @param path a path in BIP-32 format * @return the public key */ - async getPublicKey(path: string): Promise { + async getPublicKey(path: string, ecdsa?: boolean): Promise { + console.log("path: " + path); const bipPath = BIPPath.fromString(path).toPathArray(); const serializedPath = this._serializePath(bipPath); + //44/3030/0 + const p1 = 0x01; - const p2 = 0x00; + let p2 = 0x00; + + if (ecdsa) { + p2 = 1; + } + + console.log("getting key..."); const response = await this.transport.send(CLA, INS.GET_PUBLIC_KEY, p1, p2, serializedPath); + console.log(response); + const returnCodeBytes = response.slice(-2); const returnCode = (returnCodeBytes[0] << 8) | returnCodeBytes[1]; @@ -53,13 +64,17 @@ export default class Hedera { } // TODO: the BOLOS app does not support anything but index #0 for signing transactions - async signTransaction(transaction: Uint8Array): Promise { + async signTransaction(transaction: Uint8Array, ecdsa?: boolean): Promise { const payload = Buffer.alloc(4 + transaction.length); payload.writeUInt32LE(0); payload.fill(transaction, 4); const p1 = 0x00; - const p2 = 0x00; + let p2 = 0x00; + + if (ecdsa) { + p2 = 1; + } const response = await this.transport.send(CLA, INS.SIGN_TRANSACTION, p1, p2, payload); diff --git a/libs/ledgerjs/packages/hw-transport/src/Transport.ts b/libs/ledgerjs/packages/hw-transport/src/Transport.ts index d44d28217466..ec8b0b21143d 100644 --- a/libs/ledgerjs/packages/hw-transport/src/Transport.ts +++ b/libs/ledgerjs/packages/hw-transport/src/Transport.ts @@ -267,6 +267,8 @@ export default class Transport { } tracer.trace("Starting an exchange", { abortTimeoutMs }); + console.log("apdu: " + cla + " " + ins + " " + p1 + " " + p2 + " " + data); + console.log("p2: " + p2); const response = await this.exchange( // The size of the data is added in 1 byte just before `data` Buffer.concat([Buffer.from([cla, ins, p1, p2]), Buffer.from([data.length]), data]), diff --git a/libs/ledgerjs/packages/types-live/src/derivation.ts b/libs/ledgerjs/packages/types-live/src/derivation.ts index c68e50a275ea..6e0528dd5daa 100644 --- a/libs/ledgerjs/packages/types-live/src/derivation.ts +++ b/libs/ledgerjs/packages/types-live/src/derivation.ts @@ -24,7 +24,8 @@ export type DerivationMode = | "casper_wallet" | "solanaMain" | "solanaSub" - | "hederaBip44" + | "hederaBip44Ed25519" + | "hederaBip44Ecdsa" | "cardano" | "nearbip44h" | "vechain"