From 7e81d2f9483d8699bbd44652715814209968e8b7 Mon Sep 17 00:00:00 2001 From: Sztergbaum Roman Date: Thu, 9 Feb 2023 19:57:43 +0100 Subject: [PATCH] [CoinType]: Add cointype extension for wasm (#2915) --- wasm/src/CoinTypeExtension.cpp | 114 ++++++++++++++++++++++++++++++++ wasm/src/CoinTypeExtension.d.ts | 22 ++++++ wasm/tests/CoinType.test.ts | 14 +++- 3 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 wasm/src/CoinTypeExtension.cpp create mode 100644 wasm/src/CoinTypeExtension.d.ts diff --git a/wasm/src/CoinTypeExtension.cpp b/wasm/src/CoinTypeExtension.cpp new file mode 100644 index 00000000000..e6e1f0a5e27 --- /dev/null +++ b/wasm/src/CoinTypeExtension.cpp @@ -0,0 +1,114 @@ +#include +#include "WasmString.h" +#include "generated/PrivateKey.h" +#include + +using namespace emscripten; + +namespace TW::Wasm { + class CoinTypeExtension { + public: + TWCoinType mValue; + CoinTypeExtension(TWCoinType value): mValue(value) {} + + auto value() { + return mValue; + } + + auto blockchain() { + return TWCoinTypeBlockchain(mValue); + } + + auto purpose() { + return TWCoinTypePurpose(mValue); + } + + auto curve() { + return TWCoinTypeCurve(mValue); + } + + auto xpubVersion() { + return TWCoinTypeXpubVersion(mValue); + } + + auto xprvVersion() { + return TWCoinTypeXpubVersion(mValue); + } + + auto validate(const std::string& address) { + return TWCoinTypeValidate(mValue, &address); + } + + auto derivationPath() { + return TWStringToStd(TWCoinTypeDerivationPath(mValue)); + } + + auto derivationPathWithDerivation(TWDerivation derivation) { + return TWStringToStd(TWCoinTypeDerivationPathWithDerivation(mValue, derivation)); + } + + auto deriveAddress(WasmPrivateKey* privateKey) { + return TWStringToStd(TWCoinTypeDeriveAddress(mValue, privateKey->instance)); + } + + auto deriveAddressFromPublicKey(WasmPublicKey* publicKey) { + return TWStringToStd(TWCoinTypeDeriveAddressFromPublicKey(mValue, publicKey->instance)); + } + + auto HRP() { + return TWCoinTypeHRP(mValue); + } + + auto P2pkhPrefix() { + return TWCoinTypeP2pkhPrefix(mValue); + } + + auto P2shPrefix() { + return TWCoinTypeP2shPrefix(mValue); + } + + auto staticPrefix() { + return TWCoinTypeStaticPrefix(mValue); + } + + auto chainID() { + return TWStringToStd(TWCoinTypeChainId(mValue)); + } + + auto slip44ID() { + return TWCoinTypeSlip44Id(mValue); + } + + auto SS58Prefix() { + return TWCoinTypeSS58Prefix(mValue); + } + + auto publicKeyType() { + return TWCoinTypePublicKeyType(mValue); + } + }; + + EMSCRIPTEN_BINDINGS(Wasm_CoinTypeExtension) { + class_("CoinTypeExtension") + .constructor() + .function("blockchain", &CoinTypeExtension::blockchain) + .function("purpose", &CoinTypeExtension::purpose) + .function("curve", &CoinTypeExtension::curve) + .function("xpubVersion", &CoinTypeExtension::xpubVersion) + .function("xprvVersion", &CoinTypeExtension::xprvVersion) + .function("validate", &CoinTypeExtension::validate) + .function("derivationPath", &CoinTypeExtension::derivationPath) + .function("derivationPathWithDerivation", &CoinTypeExtension::derivationPathWithDerivation) + .function("deriveAddress", &CoinTypeExtension::deriveAddress, allow_raw_pointers()) + .function("deriveAddressFromPublicKey", &CoinTypeExtension::deriveAddressFromPublicKey, allow_raw_pointers()) + .function("hrp", &CoinTypeExtension::HRP) + .function("P2pkhPrefix", &CoinTypeExtension::P2pkhPrefix) + .function("P2shPrefix", &CoinTypeExtension::P2shPrefix) + .function("staticPrefix", &CoinTypeExtension::staticPrefix) + .function("chainID", &CoinTypeExtension::chainID) + .function("slip44ID", &CoinTypeExtension::slip44ID) + .function("SS58Prefix", &CoinTypeExtension::SS58Prefix) + .function("publicKeyType", &CoinTypeExtension::publicKeyType) + .function("value", &CoinTypeExtension::value); + } +} diff --git a/wasm/src/CoinTypeExtension.d.ts b/wasm/src/CoinTypeExtension.d.ts new file mode 100644 index 00000000000..f0169dffe9e --- /dev/null +++ b/wasm/src/CoinTypeExtension.d.ts @@ -0,0 +1,22 @@ +export class CoinTypeExtension { + constructor(CoinType) + value(): CoinType + blockchain(): Blockchain + purpose(): Purpose + curve(): Curve + xpubVersion(): HDVersion + xprvVersion(): HDVersion + validate(address: string): boolean + derivationPath(): string + derivationPathWithDerivation(derivation: Derivation): string + deriveAddress(privateKey: PrivateKey): string + deriveAddressFromPublicKey(publicKey: PublicKey): string + hrp(): HRP + P2pkhPrefix(): number + P2shPrefix(): number + staticPrefix(): number + chainID(): string + slip44ID(): number + SS58Prefix(): number + publicKeyType(): PublicKeyType +} diff --git a/wasm/tests/CoinType.test.ts b/wasm/tests/CoinType.test.ts index d18fdf4c60e..416949d944c 100644 --- a/wasm/tests/CoinType.test.ts +++ b/wasm/tests/CoinType.test.ts @@ -9,7 +9,7 @@ import { assert } from "chai"; describe("CoinType", () => { it("test raw value", () => { - const { CoinType } = globalThis.core; + const { CoinType, CoinTypeExtension, Blockchain, Purpose, Curve, Derivation, PrivateKey, HexCoding } = globalThis.core; assert.equal(CoinType.bitcoin.value, 0); assert.equal(CoinType.litecoin.value, 2); @@ -18,5 +18,17 @@ describe("CoinType", () => { assert.equal(CoinType.binance.value, 714); assert.equal(CoinType.cosmos.value, 118); assert.equal(CoinType.solana.value, 501); + let val = new CoinTypeExtension(CoinType.solana); + assert.equal(val.blockchain(), Blockchain.solana); + assert.equal(val.value(), CoinType.solana); + assert.equal(val.purpose(), Purpose.bip44); + assert.equal(val.curve(), Curve.ed25519); + assert.isTrue(val.validate("Bxp8yhH9zNwxyE4UqxP7a7hgJ5xTZfxNNft7YJJ2VRjT")) + assert.equal(val.derivationPath(), "m/44'/501'/0'"); + assert.equal(val.derivationPathWithDerivation(Derivation.solanaSolana), "m/44'/501'/0'/0'"); + let data = HexCoding.decode("8778cc93c6596387e751d2dc693bbd93e434bd233bc5b68a826c56131821cb63") + const key = PrivateKey.createWithData(data); + let addr = val.deriveAddress(key); + assert.equal(addr, "7v91N7iZ9mNicL8WfG6cgSCKyRXydQjLh6UYBWwm6y1Q") }); });