Skip to content

Commit

Permalink
Merge pull request #35 from BitGo/use-static-methods
Browse files Browse the repository at this point in the history
refactor: use static methods as constructors
  • Loading branch information
OttoAllmendinger committed Aug 21, 2024
2 parents a97dcd3 + 9b792a7 commit 5f95fef
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 139 deletions.
7 changes: 1 addition & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/wasm-miniscript-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
},
"dependencies": {
"@bitgo/utxo-lib": "^10.1.0",
"@bitgo/wasm-miniscript": "^1.0.0",
"@bitgo/wasm-miniscript": "0.0.0-semantic-release-managed",
"assert": "^2.1.0",
"buffer": "^6.0.3",
"crypto-browserify": "^3.12.0",
Expand Down
15 changes: 4 additions & 11 deletions packages/wasm-miniscript-ui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,11 @@
import {
descriptorFromString,
miniscriptFromBitcoinScript,
miniscriptFromString,
ScriptContext,
} from "@bitgo/wasm-miniscript";

import * as utxolib from "@bitgo/utxo-lib";
import { Descriptor, Miniscript, ScriptContext } from "@bitgo/wasm-miniscript";

import "./style.css";

import { getElement } from "./html";
import { buildOptions, getOptions, Options } from "./options";
import { getHtmlForAst } from "./htmlAST";
import { Descriptor, Miniscript } from "@bitgo/wasm-miniscript";
import { fromHex, toHex } from "./hex";
import { getShare, setShare, Share } from "./sharing";

Expand All @@ -22,7 +15,7 @@ function createMiniscriptFromBitcoinScriptDetectScriptContext(
const formats = ["tap", "segwitv0", "legacy"] as const;
for (const format of formats) {
try {
return [miniscriptFromBitcoinScript(script, format), format];
return [Miniscript.fromBitcoinScript(script, format), format];
} catch (e) {
// ignore
}
Expand Down Expand Up @@ -168,7 +161,7 @@ function applyUpdate(changedEl: HTMLElement, options: Options) {
changedEl === elEditDescriptor ||
changedEl === getElement("input-derivation-index", HTMLInputElement)
) {
const descriptor = descriptorFromString(elEditDescriptor.value, "derivable");
const descriptor = Descriptor.fromString(elEditDescriptor.value, "derivable");
setHtmlContent(elDescriptorAst, getHtmlForAst(descriptor.node()));
const descriptorAtIndex = descriptor.atDerivationIndex(options.derivationIndex);
return applyUpdateWith(
Expand All @@ -189,7 +182,7 @@ function applyUpdate(changedEl: HTMLElement, options: Options) {
changedEl === getElement("input-script-context", HTMLSelectElement)
) {
try {
const script = miniscriptFromString(elEditMiniscript.value, options.scriptContext);
const script = Miniscript.fromString(elEditMiniscript.value, options.scriptContext);
return applyUpdateWith(
changedEl,
{ descriptor: null, miniscript: script, scriptBytes: undefined, scriptAsm: undefined },
Expand Down
11 changes: 3 additions & 8 deletions packages/wasm-miniscript-ui/src/sharing.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import * as t from "io-ts";
import {
Descriptor,
descriptorFromString,
Miniscript,
miniscriptFromString,
} from "@bitgo/wasm-miniscript";
import { Descriptor, Miniscript } from "@bitgo/wasm-miniscript";
import { fromHex, toHex } from "./hex";
import { ScriptContext } from "./codec";

Expand Down Expand Up @@ -67,11 +62,11 @@ export function getShare(
}

if ("d" in v) {
return { descriptor: descriptorFromString(v.d, "derivable") };
return { descriptor: Descriptor.fromString(v.d, "derivable") };
}
if ("ms" in v && "sc" in v) {
return {
miniscript: miniscriptFromString(v.ms, v.sc),
miniscript: Miniscript.fromString(v.ms, v.sc),
scriptContext: v.sc,
};
}
Expand Down
56 changes: 17 additions & 39 deletions packages/wasm-miniscript/js/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,28 @@ import * as wasm from "./wasm/wasm_miniscript";
// and forgets to include it in the bundle
void wasm;

export type MiniscriptNode = unknown;

export type Miniscript = {
node(): MiniscriptNode;
toString(): string;
encode(): Uint8Array;
toAsmString(): string;
};

export function isMiniscript(obj: unknown): obj is Miniscript {
return obj instanceof wasm.WrapMiniscript;
}
export type DescriptorPkType = "derivable" | "definite" | "string";

export type ScriptContext = "tap" | "segwitv0" | "legacy";

export function miniscriptFromString(script: string, scriptContext: ScriptContext): Miniscript {
return wasm.miniscript_from_string(script, scriptContext);
}

export function miniscriptFromBitcoinScript(
script: Uint8Array,
scriptContext: ScriptContext,
): Miniscript {
return wasm.miniscript_from_bitcoin_script(script, scriptContext);
}
declare module "./wasm/wasm_miniscript" {
interface WrapDescriptor {
node(): unknown;
}

export type DescriptorNode = unknown;
namespace WrapDescriptor {
function fromString(descriptor: string, pkType: DescriptorPkType): WrapDescriptor;
}

export type Descriptor = {
node(): DescriptorNode;
toString(): string;
hasWildcard(): boolean;
atDerivationIndex(index: number): Descriptor;
encode(): Uint8Array;
toAsmString(): string;
scriptPubkey(): Uint8Array;
};
interface WrapMiniscript {
node(): unknown;
}

export function isDescriptor(obj: unknown): obj is Descriptor {
return obj instanceof wasm.WrapDescriptor;
namespace WrapMiniscript {
function fromString(miniscript: string, ctx: ScriptContext): WrapMiniscript;
function fromBitcoinScript(script: Uint8Array, ctx: ScriptContext): WrapMiniscript;
}
}

type DescriptorPkType = "derivable" | "definite" | "string";

export function descriptorFromString(descriptor: string, pkType: DescriptorPkType): Descriptor {
return wasm.descriptor_from_string(descriptor, pkType);
}
export { WrapDescriptor as Descriptor } from "./wasm/wasm_miniscript";
export { WrapMiniscript as Miniscript } from "./wasm/wasm_miniscript";
52 changes: 24 additions & 28 deletions packages/wasm-miniscript/src/descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use std::str::FromStr;
use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
use miniscript::bitcoin::ScriptBuf;
use crate::try_into_js_value::TryIntoJsValue;
use miniscript::bitcoin::secp256k1::Secp256k1;
use miniscript::bitcoin::ScriptBuf;
use miniscript::descriptor::KeyMap;
use miniscript::{DefiniteDescriptorKey, Descriptor, DescriptorPublicKey};
use std::str::FromStr;
use wasm_bindgen::prelude::wasm_bindgen;
use wasm_bindgen::{JsError, JsValue};
use crate::try_into_js_value::TryIntoJsValue;

enum WrapDescriptorEnum {
Derivable(Descriptor<DescriptorPublicKey>, KeyMap),
Expand Down Expand Up @@ -58,18 +58,14 @@ impl WrapDescriptor {
#[wasm_bindgen(js_name = scriptPubkey)]
pub fn script_pubkey(&self) -> Result<Vec<u8>, JsError> {
match &self.0 {
WrapDescriptorEnum::Definite(desc) => {
Ok(desc.script_pubkey().to_bytes())
}
WrapDescriptorEnum::Definite(desc) => Ok(desc.script_pubkey().to_bytes()),
_ => Err(JsError::new("Cannot derive from a non-definite descriptor")),
}
}

fn explicit_script(&self) -> Result<ScriptBuf, JsError> {
match &self.0 {
WrapDescriptorEnum::Definite(desc) => {
Ok(desc.explicit_script()?)
}
WrapDescriptorEnum::Definite(desc) => Ok(desc.explicit_script()?),
WrapDescriptorEnum::Derivable(_, _) => {
Err(JsError::new("Cannot encode a derivable descriptor"))
}
Expand All @@ -85,24 +81,24 @@ impl WrapDescriptor {
pub fn to_asm_string(&self) -> Result<String, JsError> {
Ok(self.explicit_script()?.to_asm_string())
}
}

#[wasm_bindgen]
pub fn descriptor_from_string(descriptor: &str, pk_type: &str) -> Result<WrapDescriptor, JsError> {
match pk_type {
"derivable" => {
let secp = Secp256k1::new();
let (desc, keys) = Descriptor::parse_descriptor(&secp, descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::Derivable(desc, keys)))
}
"definite" => {
let desc = Descriptor::<DefiniteDescriptorKey>::from_str(descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::Definite(desc)))
}
"string" => {
let desc = Descriptor::<String>::from_str(descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::String(desc)))
#[wasm_bindgen(js_name = fromString, skip_typescript)]
pub fn from_string(descriptor: &str, pk_type: &str) -> Result<WrapDescriptor, JsError> {
match pk_type {
"derivable" => {
let secp = Secp256k1::new();
let (desc, keys) = Descriptor::parse_descriptor(&secp, descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::Derivable(desc, keys)))
}
"definite" => {
let desc = Descriptor::<DefiniteDescriptorKey>::from_str(descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::Definite(desc)))
}
"string" => {
let desc = Descriptor::<String>::from_str(descriptor)?;
Ok(WrapDescriptor(WrapDescriptorEnum::String(desc)))
}
_ => Err(JsError::new("Invalid descriptor type")),
}
_ => Err(JsError::new("Invalid descriptor type")),
}
}
}
5 changes: 2 additions & 3 deletions packages/wasm-miniscript/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@ mod miniscript;
mod error;
mod descriptor;

pub use miniscript::miniscript_from_string;
pub use miniscript::miniscript_from_bitcoin_script;
pub use descriptor::descriptor_from_string;
pub use miniscript::WrapMiniscript;
pub use descriptor::WrapDescriptor;
72 changes: 36 additions & 36 deletions packages/wasm-miniscript/src/miniscript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,42 @@ impl WrapMiniscript {
pub fn to_asm_string(&self) -> Result<String, JsError> {
unwrap_apply!(&self.0, |ms| Ok(ms.encode().to_asm_string()))
}

#[wasm_bindgen(js_name = fromString, skip_typescript)]
pub fn from_string(script: &str, context_type: &str) -> Result<WrapMiniscript, JsError> {
match context_type {
"tap" => Ok(WrapMiniscript::from(
Miniscript::<XOnlyPublicKey, Tap>::from_str(script).map_err(JsError::from)?,
)),
"segwitv0" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Segwitv0>::from_str(script).map_err(JsError::from)?,
)),
"legacy" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Legacy>::from_str(script).map_err(JsError::from)?,
)),
_ => Err(JsError::new("Invalid context type")),
}
}

#[wasm_bindgen(js_name = fromBitcoinScript, skip_typescript)]
pub fn from_bitcoin_script(
script: &[u8],
context_type: &str,
) -> Result<WrapMiniscript, JsError> {
let script = bitcoin::Script::from_bytes(script);
match context_type {
"tap" => Ok(WrapMiniscript::from(
Miniscript::<XOnlyPublicKey, Tap>::parse(script).map_err(JsError::from)?,
)),
"segwitv0" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Segwitv0>::parse(script).map_err(JsError::from)?,
)),
"legacy" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Legacy>::parse(script).map_err(JsError::from)?,
)),
_ => Err(JsError::new("Invalid context type")),
}
}
}

impl From<Miniscript<XOnlyPublicKey, Tap>> for WrapMiniscript {
Expand All @@ -68,42 +104,6 @@ impl From<Miniscript<PublicKey, Legacy>> for WrapMiniscript {
}
}

#[wasm_bindgen]
pub fn miniscript_from_string(script: &str, context_type: &str) -> Result<WrapMiniscript, JsError> {
match context_type {
"tap" => Ok(WrapMiniscript::from(
Miniscript::<XOnlyPublicKey, Tap>::from_str(script).map_err(JsError::from)?,
)),
"segwitv0" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Segwitv0>::from_str(script).map_err(JsError::from)?,
)),
"legacy" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Legacy>::from_str(script).map_err(JsError::from)?,
)),
_ => Err(JsError::new("Invalid context type")),
}
}

#[wasm_bindgen]
pub fn miniscript_from_bitcoin_script(
script: &[u8],
context_type: &str,
) -> Result<WrapMiniscript, JsError> {
let script = bitcoin::Script::from_bytes(script);
match context_type {
"tap" => Ok(WrapMiniscript::from(
Miniscript::<XOnlyPublicKey, Tap>::parse(script).map_err(JsError::from)?,
)),
"segwitv0" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Segwitv0>::parse(script).map_err(JsError::from)?,
)),
"legacy" => Ok(WrapMiniscript::from(
Miniscript::<PublicKey, Legacy>::parse(script).map_err(JsError::from)?,
)),
_ => Err(JsError::new("Invalid context type")),
}
}

#[test]
pub fn panic_xprv() {
use miniscript::bitcoin::secp256k1::Secp256k1;
Expand Down
Loading

0 comments on commit 5f95fef

Please sign in to comment.