Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
hzheng-ledger committed Feb 11, 2022
1 parent ddb49f7 commit d7e97bc
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 52 deletions.
78 changes: 78 additions & 0 deletions src/__tests__/families/bitcoin/wallet-btc/xpub.getAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { DerivationModes } from "../../../../families/bitcoin/wallet-btc";
import BitcoinLikeStorage from "../../../../families/bitcoin/wallet-btc/storage";
import BitcoinLikeExplorer from "../../../../families/bitcoin/wallet-btc/explorer";
import Xpub from "../../../../families/bitcoin/wallet-btc/xpub";
import coininfo from "coininfo";
import BCHCrypto from "../../../../families/bitcoin/wallet-btc/crypto/bitcoincash";
import BTCCrypto from "../../../../families/bitcoin/wallet-btc/crypto/bitcoin";
import ZECCrypto from "../../../../families/bitcoin/wallet-btc/crypto/zec";
import ZENCrypto from "../../../../families/bitcoin/wallet-btc/crypto/zen";

describe("Unit tests for getAddress", () => {
it("Test getAddress for bch and btc", async () => {
const bchCrypto = new BCHCrypto({
network: coininfo.bitcoincash.main.toBitcoinJS(),
});
const btcCrypto = new BTCCrypto({
network: coininfo.bitcoin.main.toBitcoinJS(),
});
const bchxpub = new Xpub({
storage: new BitcoinLikeStorage(),
explorer: new BitcoinLikeExplorer({
explorerURI: "https://explorers.api.vault.ledger.com/blockchain/v3/bch",
explorerVersion: "v3",
}),
crypto: bchCrypto,
xpub: "xpub6BtWBf3Pu6hYwJBKvEwG7JtrTxxDrSGy39HaTgZz6GTSaFWFdoCtuEXSQtoKGaYdz1emg8xTXKYwjhu3xXRPzFnYS1z4yjKj7hLDQyNeDZr",
derivationMode: DerivationModes.LEGACY,
});
await bchxpub.syncAddress(0, 0);
let addresses = await bchxpub.getXpubAddresses();
expect(addresses[0].address).toEqual(
"bitcoincash:qrgwhfg7tn4xs9pg2vu5rhkud490j9yfnqd63uk64m"
);

const btcxpub = new Xpub({
storage: new BitcoinLikeStorage(),
explorer: new BitcoinLikeExplorer({
explorerURI: "https://explorers.api.vault.ledger.com/blockchain/v3/btc",
explorerVersion: "v3",
}),
crypto: btcCrypto,
xpub: "xpub6BtWBf3Pu6hYwJBKvEwG7JtrTxxDrSGy39HaTgZz6GTSaFWFdoCtuEXSQtoKGaYdz1emg8xTXKYwjhu3xXRPzFnYS1z4yjKj7hLDQyNeDZr",
derivationMode: DerivationModes.LEGACY,
});
await btcxpub.syncAddress(0, 0);
addresses = await btcxpub.getXpubAddresses();
expect(addresses[0].address).toEqual("1L3fqoWstvLqEA6TgXkuLoXX8xG1xhirG3");
}, 60000);

it("Test getoutputScriptFromAddress for btc, zcash and zen", async () => {
const btcCrypto = new BTCCrypto({
network: coininfo.bitcoin.main.toBitcoinJS(),
});
const zecCrypto = new ZECCrypto({
network: coininfo.zcash.main.toBitcoinJS(),
});
const zenCrypto = new ZENCrypto({
network: coininfo.zcash.main.toBitcoinJS(),
});
expect(
btcCrypto
.toOutputScript("1F1tAaz5x1HUXrCNLbtMDqcw6o5GNn4xqX")
.toString("hex")
).toEqual("76a91499bc78ba577a95a11f1a344d4d2ae55f2f857b9888ac");
expect(
zecCrypto
.toOutputScript("t1T5XJvzQhh2gTsi3c5Vn9x5SMhpSWLSnVy")
.toString("hex")
).toEqual("76a91464fa33fb6f8d72455af2a4e73ae30412af2c97ba88ac");
expect(
zenCrypto
.toOutputScript("znjbHth4PxBJM8FmHgvXYHkuq99nKFkWvMg")
.toString("hex")
).toEqual(
"76a914cb009bf12fc17d28e61527951101fdabfeaa187288ac209ec9845acb02fab24e1c0368b3b517c1a4488fba97f0e3459ac053ea0100000003c01f02b4"
);
}, 30000);
});
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ describe("xpub integration sync", () => {
coin: "dgb",
explorerVersion: "v3",
},
/*
{
xpub: "xpub6CUGRUonZSQ4TWtTMmzXdrXDtypWKiKrhko4egpiMZbpiaQL2jkwSB1icqYh2cfDfVxdx4df189oLKnC5fSwqPfgyP3hooxujYzAu3fDVmz", // 3000ms
derivationMode: DerivationModes.LEGACY,
Expand All @@ -71,6 +72,7 @@ describe("xpub integration sync", () => {
coin: "btc",
explorerVersion: "v3",
},
*/
{
xpub: "xpub6D4waFVPfPCpRvPkQd9A6n65z3hTp6TvkjnBHG5j2MCKytMuadKgfTUHqwRH77GQqCKTTsUXSZzGYxMGpWpJBdYAYVH75x7yMnwJvra1BUJ", // 5400ms
derivationMode: DerivationModes.LEGACY,
Expand Down
4 changes: 2 additions & 2 deletions src/families/bitcoin/wallet-btc/crypto/bip32.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import ecc from "tiny-secp256k1";
import { publicKeyTweakAdd } from "secp256k1";
import createHmac from "create-hmac";

// the BIP32 class is inspired from https://github.com/bitcoinjs/bip32/blob/master/src/bip32.js
Expand Down Expand Up @@ -28,7 +28,7 @@ class BIP32 {
const I = createHmac("sha512", this.chainCode).update(data).digest();
const IL = I.slice(0, 32);
const IR = I.slice(32);
const Ki = ecc.pointAddScalar(this.publicKey, IL, true);
const Ki = Buffer.from(publicKeyTweakAdd(this.publicKey, IL));
return new BIP32(Ki, IR, this.network, this.depth + 1, index);
}
}
Expand Down
42 changes: 21 additions & 21 deletions src/families/bitcoin/wallet-btc/crypto/zec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { toOutputScript } from "bitcoinjs-lib/src/address";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import zec from "zcash-bitcore-lib";
import bs58check from "bs58check";
import coininfo from "coininfo";
import * as bjs from "bitcoinjs-lib";
import { InvalidAddress } from "@ledgerhq/errors";
import { DerivationModes } from "../types";
import { ICrypto } from "./types";
import Base from "./base";

class ZCash implements ICrypto {
class ZCash extends Base {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
network: any;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor({ network }: { network: any }) {
super({ network });
this.network = network;
this.network.dustThreshold = 10000;
this.network.dustPolicy = "FIXED";
Expand All @@ -32,19 +29,13 @@ class ZCash implements ICrypto {
return bs58check.encode(Buffer.from(taddr));
}

private static toBitcoinAddr(taddr: string) {
// refer to https://runkitcdn.com/gojomo/baddr2taddr/1.0.2
const baddr = new Uint8Array(21);
baddr.set(bs58check.decode(taddr).slice(2), 1);
return bs58check.encode(Buffer.from(baddr));
}

// eslint-disable-next-line
getLegacyAddress(xpub: string, account: number, index: number): string {
const pubkey = new zec.HDPublicKey(xpub);
const child = pubkey.derive(account).derive(index);
const address = new zec.Address(child.publicKey, zec.Networks.livenet);
return address.toString();
const pk = bjs.crypto.hash160(this.getPubkeyAt(xpub, account, index));
const payload = Buffer.allocUnsafe(22);
payload.writeUInt16BE(this.network.pubKeyHash, 0);
pk.copy(payload, 2);
return bs58check.encode(payload);
}

getAddress(
Expand Down Expand Up @@ -78,11 +69,20 @@ class ZCash implements ICrypto {
if (!this.validateAddress(address)) {
throw new InvalidAddress();
}
// TODO find a better way to calculate the script from zec address instead of converting to bitcoin address
return toOutputScript(
ZCash.toBitcoinAddr(address),
coininfo.bitcoin.main.toBitcoinJS()
const version = Number(
"0x" + bs58check.decode(address).slice(0, 2).toString("hex")
);
if (version === this.network.pubKeyHash) {
//Pay-to-PubkeyHash
return bjs.payments.p2pkh({ hash: bs58check.decode(address).slice(2) })
.output as Buffer;
}
if (version === this.network.scriptHash) {
//Pay-to-Script-Hash
return bjs.payments.p2sh({ hash: bs58check.decode(address).slice(2) })
.output as Buffer;
}
throw new InvalidAddress();
}

// eslint-disable-next-line class-methods-use-this
Expand Down
57 changes: 28 additions & 29 deletions src/families/bitcoin/wallet-btc/crypto/zen.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { toOutputScript } from "bitcoinjs-lib/src/address";
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import zec from "zcash-bitcore-lib";
import bs58check from "bs58check";
import coininfo from "coininfo";
import { InvalidAddress } from "@ledgerhq/errors";
import { DerivationModes } from "../types";
import { ICrypto } from "./types";
import Base from "./base";
import * as bjs from "bitcoinjs-lib";

class Zen implements ICrypto {
class Zen extends Base {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
network: any;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor({ network }: { network: any }) {
super({ network });
// refer to https://github.com/HorizenOfficial/zen/blob/master/src/chainparams.cpp for the blockchain params
this.network = network;
this.network.versions = {
Expand All @@ -26,15 +20,15 @@ class Zen implements ICrypto {
},
bip44: 121,
private: 0x80,
public: 0x2096,
scripthash: 0x2089,
public: 0x2089,
scripthash: 0x2096,
};
this.network.name = "Zencash";
this.network.unit = "ZEN";
this.network.messagePrefix = "Zencash Signed Message:\n";
this.network.wif = 0x80;
this.network.pubKeyHash = 0x2096;
this.network.scriptHash = 0x2089;
this.network.pubKeyHash = 0x2089;
this.network.scriptHash = 0x2096;
this.network.dustThreshold = 10000;
this.network.dustPolicy = "FIXED";
this.network.usesTimestampedTransaction = false;
Expand All @@ -50,21 +44,13 @@ class Zen implements ICrypto {
return bs58check.encode(Buffer.from(taddr));
}

private static toBitcoinAddr(taddr: string) {
// refer to https://runkitcdn.com/gojomo/baddr2taddr/1.0.2
const baddr = new Uint8Array(21);
baddr.set(bs58check.decode(taddr).slice(2), 1);
return bs58check.encode(Buffer.from(baddr));
}

// eslint-disable-next-line
getLegacyAddress(xpub: string, account: number, index: number): string {
const pubkey = new zec.HDPublicKey(xpub);
const child = pubkey.derive(account).derive(index);
const address = new zec.Address(child.publicKey, zec.Networks.livenet);
const baddr = new Uint8Array(21);
baddr.set(bs58check.decode(address.toString()).slice(2), 1);
return this.baddrToTaddr(bs58check.encode(Buffer.from(baddr)));
const pk = bjs.crypto.hash160(this.getPubkeyAt(xpub, account, index));
const payload = Buffer.allocUnsafe(22);
payload.writeUInt16BE(this.network.pubKeyHash, 0);
pk.copy(payload, 2);
return bs58check.encode(payload);
}

getAddress(
Expand Down Expand Up @@ -98,10 +84,23 @@ class Zen implements ICrypto {
if (!this.validateAddress(address)) {
throw new InvalidAddress();
}
const outputScript = toOutputScript(
Zen.toBitcoinAddr(address),
coininfo.bitcoin.main.toBitcoinJS()
let outputScript: Buffer;
const version = Number(
"0x" + bs58check.decode(address).slice(0, 2).toString("hex")
);
if (version === this.network.pubKeyHash) {
//Pay-to-PubkeyHash
outputScript = bjs.payments.p2pkh({
hash: bs58check.decode(address).slice(2),
}).output as Buffer;
} else if (version === this.network.scriptHash) {
//Pay-to-Script-Hash
outputScript = bjs.payments.p2sh({
hash: bs58check.decode(address).slice(2),
}).output as Buffer;
} else {
throw new InvalidAddress();
}
// refer to https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/scripts/BitcoinLikeScript.cpp#L139 and https://github.com/LedgerHQ/lib-ledger-core/blob/fc9d762b83fc2b269d072b662065747a64ab2816/core/src/wallet/bitcoin/networks.cpp#L39 for bip115 Script and its network parameters
const bip115Script = Buffer.from(
"209ec9845acb02fab24e1c0368b3b517c1a4488fba97f0e3459ac053ea0100000003c01f02b4",
Expand Down

0 comments on commit d7e97bc

Please sign in to comment.