Skip to content

Commit 5b01d61

Browse files
Merge pull request #14 from BitGo/BTC-2652.altcoin-address-encoding
feat(wasm-utxo): extend address generation for altcoin wallets
2 parents e570194 + 6a923e3 commit 5b01d61

File tree

12 files changed

+1296
-29
lines changed

12 files changed

+1296
-29
lines changed

packages/wasm-utxo/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ edition = "2021"
66
[lib]
77
crate-type = ["cdylib"]
88

9+
[lints.clippy]
10+
all = "warn"
11+
912
[dependencies]
1013
wasm-bindgen = "0.2"
1114
js-sys = "0.3"

packages/wasm-utxo/README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ that help verify and co-sign transactions built by the BitGo Wallet Platform API
99

1010
This project is under active development.
1111

12-
| Feature | Bitcoin | BitcoinCash | BitcoinGold | Dash | Doge | Litecoin | Zcash |
13-
| --------------------------------------- | -------------- | ----------- | ----------- | ------- | ------- | -------- | ------- |
14-
| Descriptor Wallet: Address Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
15-
| Descriptor Wallet: Transaction Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
16-
| FixedScript Wallet: Address Generation | 🏗️ In Progress | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO |
17-
| FixedScript Wallet: Transaction Support | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO |
12+
| Feature | Bitcoin | BitcoinCash | BitcoinGold | Dash | Doge | Litecoin | Zcash |
13+
| --------------------------------------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- | ----------- |
14+
| Descriptor Wallet: Address Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
15+
| Descriptor Wallet: Transaction Support | ✅ Complete | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 | 🚫 |
16+
| FixedScript Wallet: Address Generation | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete | ✅ Complete |
17+
| FixedScript Wallet: Transaction Support | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO | ⏳ TODO |
1818

1919
## Building
2020

packages/wasm-utxo/js/index.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,36 @@ export type DescriptorPkType = "derivable" | "definite" | "string";
88

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

11+
export type AddressFormat = "default" | "cashaddr";
12+
1113
export type SignPsbtResult = {
1214
[inputIndex: number]: [pubkey: string][];
1315
};
1416

17+
// BitGo coin names (from Network::from_coin_name in src/networks.rs)
18+
export type CoinName =
19+
| "btc"
20+
| "tbtc"
21+
| "tbtc4"
22+
| "tbtcsig"
23+
| "tbtcbgsig"
24+
| "bch"
25+
| "tbch"
26+
| "bcha"
27+
| "tbcha"
28+
| "btg"
29+
| "tbtg"
30+
| "bsv"
31+
| "tbsv"
32+
| "dash"
33+
| "tdash"
34+
| "doge"
35+
| "tdoge"
36+
| "ltc"
37+
| "tltc"
38+
| "zec"
39+
| "tzec";
40+
1541
declare module "./wasm/wasm_utxo" {
1642
interface WrapDescriptor {
1743
/** These are not the same types of nodes as in the ast module */
@@ -37,16 +63,46 @@ declare module "./wasm/wasm_utxo" {
3763
signWithXprv(this: WrapPsbt, xprv: string): SignPsbtResult;
3864
signWithPrv(this: WrapPsbt, prv: Uint8Array): SignPsbtResult;
3965
}
66+
67+
interface Address {
68+
/**
69+
* Convert output script to address string
70+
* @param script - The output script as a byte array
71+
* @param network - The utxolib Network object from JavaScript
72+
* @param format - Optional address format: "default" or "cashaddr" (only applicable for Bitcoin Cash and eCash)
73+
*/
74+
fromOutputScript(script: Uint8Array, network: any, format?: AddressFormat): string;
75+
/**
76+
* Convert address string to output script
77+
* @param address - The address string
78+
* @param network - The utxolib Network object from JavaScript
79+
* @param format - Optional address format (currently unused for decoding as all formats are accepted)
80+
*/
81+
toOutputScript(address: string, network: any, format?: AddressFormat): Uint8Array;
82+
}
4083
}
4184

4285
import { Address as WasmAddress } from "./wasm/wasm_utxo";
4386

4487
export { WrapDescriptor as Descriptor } from "./wasm/wasm_utxo";
4588
export { WrapMiniscript as Miniscript } from "./wasm/wasm_utxo";
4689
export { WrapPsbt as Psbt } from "./wasm/wasm_utxo";
90+
export { FixedScriptWallet } from "./wasm/wasm_utxo";
4791

4892
export namespace utxolibCompat {
4993
export const Address = WasmAddress;
5094
}
5195

96+
export function toOutputScriptWithCoin(address: string, coin: CoinName): Uint8Array {
97+
return wasm.toOutputScriptWithCoin(address, coin);
98+
}
99+
100+
export function fromOutputScriptWithCoin(
101+
script: Uint8Array,
102+
coin: CoinName,
103+
format?: AddressFormat,
104+
): string {
105+
return wasm.fromOutputScriptWithCoin(script, coin, format);
106+
}
107+
52108
export * as ast from "./ast";

packages/wasm-utxo/src/address/cashaddr.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Cashaddr encoding/decoding module for Bitcoin Cash and eCash.
22
//!
33
//! Implements the cashaddr checksum algorithm as defined in:
4-
//! - Spec: https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md
5-
//! - Reference implementation: https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/src/cashaddr.cpp
4+
//! - Spec: <https://github.com/bitcoincashorg/bitcoincash.org/blob/master/spec/cashaddr.md>
5+
//! - Reference implementation: <https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/src/cashaddr.cpp>
66
//!
77
//! This implementation directly follows the official specification and passes all test vectors.
88
//!

packages/wasm-utxo/src/address/mod.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@
3535
mod base58check;
3636
mod bech32;
3737
pub mod cashaddr;
38+
pub mod networks;
3839
pub mod utxolib_compat;
3940

4041
pub use base58check::Base58CheckCodec;
4142
pub use bech32::Bech32Codec;
4243
pub use cashaddr::CashAddrCodec;
44+
pub use networks::{
45+
from_output_script_with_coin, from_output_script_with_network, to_output_script_with_coin,
46+
to_output_script_with_network,
47+
};
4348

4449
use crate::bitcoin::{Script, ScriptBuf};
4550
use std::fmt;
@@ -172,11 +177,6 @@ pub fn from_output_script(script: &Script, codec: &dyn AddressCodec) -> Result<S
172177
codec.encode(script)
173178
}
174179

175-
/// Convert address string to output script (convenience wrapper)
176-
pub fn to_output_script(address: &str, codec: &dyn AddressCodec) -> Result<ScriptBuf> {
177-
codec.decode(address)
178-
}
179-
180180
/// Try multiple codecs to decode an address
181181
pub fn to_output_script_try_codecs(
182182
address: &str,
@@ -200,6 +200,11 @@ mod tests {
200200
use crate::bitcoin::hashes::Hash;
201201
use crate::bitcoin::PubkeyHash;
202202

203+
/// Convert address string to output script (convenience wrapper)
204+
pub fn to_output_script(address: &str, codec: &dyn AddressCodec) -> Result<ScriptBuf> {
205+
codec.decode(address)
206+
}
207+
203208
#[test]
204209
fn test_base58_roundtrip() {
205210
let hash = hex::decode("1e231c7f9b3415daaa53ee5a7e12e120f00ec212").unwrap();

0 commit comments

Comments
 (0)