Skip to content

Commit

Permalink
feat: refactors bcur and coldcard to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinRiggen authored and bucko13 committed Nov 6, 2023
1 parent 6faa816 commit 2816238
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 27 deletions.
File renamed without changes.
36 changes: 20 additions & 16 deletions src/bcur.js → src/bcur.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,20 @@ import { encodeUR, smartDecodeUR } from "./vendor/bcur";
* const encoder = BCUREncoder(hexString);
* console.log(encoder.parts())
* // [ "ur:...", "ur:...", ... ]
*
*
*
*/
export class BCUREncoder {
hexString: string;

fragmentCapacity: number;

/**
* Create a new encoder.
*
* @param {string} hexString a hex string to encode
* @param {int} fragmentCapacity passed to internal bcur implementation
*
*
*/
constructor(hexString, fragmentCapacity = 200) {
this.hexString = hexString;
Expand All @@ -48,12 +51,11 @@ export class BCUREncoder {
* Return all UR parts.
*
* @returns {string[]} array of BC UR strings
*
*
*/
parts() {
return encodeUR(this.hexString, this.fragmentCapacity);
}

}

/**
Expand Down Expand Up @@ -84,16 +86,20 @@ export class BCUREncoder {
*
* // Data can be passed back to the calling application
* console.log(decoder.data()); // "deadbeef"
*
*
* } else {
*
* // Errors can be passed back to the calling application
* console.log(decoder.errorMessage());
* }
*
*
*
*
*/
export class BCURDecoder {
// TODO: type these
error: any;

summary: any;

constructor() {
this.reset();
Expand All @@ -112,7 +118,7 @@ export class BCURDecoder {
current: 0,
length: 0,
workloads: [],
result: '',
result: "",
};
this.error = null;
}
Expand All @@ -127,12 +133,11 @@ export class BCURDecoder {
*/
receivePart(part) {
try {
const workloads = this.summary.workloads.includes(part) ? this.summary.workloads : [
...this.summary.workloads,
part,
];
const workloads = this.summary.workloads.includes(part)
? this.summary.workloads
: [...this.summary.workloads, part];
this.summary = smartDecodeUR(workloads);
} catch(e) {
} catch (e) {
this.error = e;
}
}
Expand All @@ -155,12 +160,12 @@ export class BCURDecoder {
* ...
* console.log(decoder.progress())
* // { totalParts: 10, partsReceived: 3 }
*
*
*/
progress() {
const totalParts = this.summary.length;
const partsReceived = this.summary.current;
return {totalParts, partsReceived};
return { totalParts, partsReceived };
}

/**
Expand Down Expand Up @@ -210,5 +215,4 @@ export class BCURDecoder {
return null;
}
}

}
14 changes: 10 additions & 4 deletions src/coldcard.test.js → src/coldcard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const { multisigs, transactions } = TEST_FIXTURES;
const { nodes } = TEST_FIXTURES.keys.open_source;

describe("ColdcardExportPublicKey", () => {
function interactionBuilder({ bip32Path, network }) {
function interactionBuilder({ bip32Path = "", network = "" }) {
return new ColdcardExportPublicKey({
bip32Path,
network,
Expand Down Expand Up @@ -274,7 +274,7 @@ describe("ColdcardExportPublicKey", () => {
});

describe("ColdcardExportExtendedPublicKey", () => {
function interactionBuilder({ bip32Path, network }) {
function interactionBuilder({ bip32Path = "", network = "" }) {
return new ColdcardExportExtendedPublicKey({
bip32Path,
network,
Expand Down Expand Up @@ -492,7 +492,13 @@ describe("ColdcardExportExtendedPublicKey", () => {
});

describe("ColdcardSignMultisigTransaction", () => {
function interactionBuilder({ network, inputs, outputs, bip32Paths, psbt }) {
function interactionBuilder({
network = "",
inputs = [],
outputs = [],
bip32Paths = [],
psbt = "",
}) {
return new ColdcardSignMultisigTransaction({
network,
inputs,
Expand Down Expand Up @@ -648,7 +654,7 @@ describe("ColdcardSignMultisigTransaction", () => {
});

describe("ColdcardMultisigWalletConfig", () => {
let jsonConfigCopy = "";
let jsonConfigCopy: any = {};

beforeEach(() => {
// runs before each test in this block
Expand Down
48 changes: 41 additions & 7 deletions src/coldcard.js → src/coldcard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
ERROR,
} from "./interaction";
import { P2SH, P2SH_P2WSH, P2WSH } from "unchained-bitcoin";
import { BitcoinNetwork } from "unchained-bitcoin";

export const COLDCARD = "coldcard";
// Our constants use 'P2SH-P2WSH', their file uses 'P2SH_P2WSH' :\
Expand Down Expand Up @@ -64,6 +65,14 @@ class ColdcardMultisigSettingsFileParser extends ColdcardInteraction {
* @param {string} options.network - bitcoin network (needed for derivations)
* @param {string} options.bip32Path - bip32Path to interrogate
*/
network: BitcoinNetwork;

bip32Path: string;

bip32ValidationErrorMessage: any;

bip32ValidationError: string;

constructor({ network, bip32Path }) {
super();
if ([MAINNET, TESTNET].find((net) => net === network)) {
Expand Down Expand Up @@ -242,7 +251,8 @@ class ColdcardMultisigSettingsFileParser extends ColdcardInteraction {
// because the xpub includes its parent's fingerprint.
let xfpFromWithinXpub =
xpubClass.depth === 1
? fingerprintToFixedLengthHex(xpubClass.parentFingerprint)
? xpubClass.parentFingerprint &&
fingerprintToFixedLengthHex(xpubClass.parentFingerprint)
: null;

// Sanity check if you send in a depth one xpub, we should get the same fingerprint
Expand Down Expand Up @@ -275,11 +285,13 @@ class ColdcardMultisigSettingsFileParser extends ColdcardInteraction {
*/
deriveDeeperXpubIfNecessary(result) {
const knownColdcardChroot = this.chrootForBIP32Path(this.bip32Path);
let relativePath = getRelativeBIP32Path(
knownColdcardChroot,
this.bip32Path
);
let addressType = COLDCARD_BASE_BIP32_PATHS[knownColdcardChroot];
let relativePath =
knownColdcardChroot &&
getRelativeBIP32Path(knownColdcardChroot, this.bip32Path);
let addressType;
if (knownColdcardChroot !== null) {
addressType = COLDCARD_BASE_BIP32_PATHS[knownColdcardChroot];
}
// result could have p2wsh_p2sh or p2sh_p2wsh based on firmware version. Blah!
if (addressType.includes("_") && !result[addressType.toLowerCase()]) {
// Firmware < v3.2.0
Expand All @@ -293,7 +305,7 @@ class ColdcardMultisigSettingsFileParser extends ColdcardInteraction {
? convertExtendedPublicKey(result[addressType.toLowerCase()], prefix)
: result[addressType.toLowerCase()];

return relativePath.length
return relativePath && relativePath.length
? deriveChildExtendedPublicKey(baseXpub, relativePath, this.network)
: baseXpub;
}
Expand Down Expand Up @@ -419,6 +431,16 @@ export class ColdcardSignMultisigTransaction extends ColdcardInteraction {
* @param {array<string>} options.bip32Paths - BIP32 paths
* @param {object} [options.psbt] - PSBT of the transaction to sign, include it or we will generate it
*/
network: string;

psbt: any;

inputs: any[];

outputs: any[];

bip32Paths: string[];

constructor({ network, inputs, outputs, bip32Paths, psbt }) {
super();
this.network = network;
Expand Down Expand Up @@ -550,6 +572,18 @@ export class ColdcardSignMultisigTransaction extends ColdcardInteraction {
*
*/
export class ColdcardMultisigWalletConfig {
jsonConfig: any;

name: string;

requiredSigners: number;

totalSigners: number;

addressType: string;

extendedPublicKeys: any[];

constructor({ jsonConfig }) {
if (typeof jsonConfig === "object") {
this.jsonConfig = jsonConfig;
Expand Down
7 changes: 7 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,10 @@ export interface MultisigWalletConfig {
// signers in the quorum (equal to extendedPublicKeys.length)
ledgerPolicyHmacs?: LedgerPolicyHmacs[];
}

// This is currently only used in bcur.ts
export interface Summary {
success: boolean;
current: number;
length: number;
}

0 comments on commit 2816238

Please sign in to comment.