Skip to content

Commit

Permalink
Merge commit 'a0845b9ec9b1f97f3aea050f22a8105dd62b994e'
Browse files Browse the repository at this point in the history
  • Loading branch information
asi345 committed Nov 1, 2023
2 parents 5411d26 + a0845b9 commit 29d4368
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 10 deletions.
13 changes: 6 additions & 7 deletions examples/btc_sign_msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,12 @@ async fn signmsg<R: bitbox_api::runtime::Runtime>() {

let keypath = bitbox_api::Keypath::try_from("m/49'/0'/0'/0/0").unwrap();

let script_config_sign_msg: Option<pb::BtcScriptConfigWithKeypath> =
Some(pb::BtcScriptConfigWithKeypath {
script_config: Some(bitbox_api::btc::make_script_config_simple(
pb::btc_script_config::SimpleType::P2wpkhP2sh,
)),
keypath: keypath.to_vec(),
});
let script_config_sign_msg: pb::BtcScriptConfigWithKeypath = pb::BtcScriptConfigWithKeypath {
script_config: Some(bitbox_api::btc::make_script_config_simple(
pb::btc_script_config::SimpleType::P2wpkhP2sh,
)),
keypath: keypath.to_vec(),
};

let signature = paired_bitbox
.btc_sign_message(pb::BtcCoin::Btc, script_config_sign_msg, b"message")
Expand Down
84 changes: 84 additions & 0 deletions sandbox/src/Bitcoin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,87 @@ function BtcSignPSBT({ bb02 }: Props) {
);
}

function BtcSignMessage({ bb02 }: Props) {
const [simpleType, setSimpleType] = useState<bitbox.BtcSimpleType>('p2wpkhP2sh');
const [keypath, setKeypath] = useState("m/49'/0'/0'/0/0");
const [message, setMessage] = useState('message');
const [running, setRunning] = useState(false);
const [result, setResult] = useState<bitbox.BtcSignMessageSignature | undefined>();
const [err, setErr] = useState<bitbox.Error>();

const coin = 'btc';
const simpleTypeOptions: bitbox.BtcSimpleType[] = ['p2wpkhP2sh', 'p2wpkh'];

const scriptConfig: bitbox.BtcScriptConfig = { simpleType };
const scriptConfigWKeypath: bitbox.BtcScriptConfigWithKeypath = { scriptConfig, keypath };

const stringToUint8Array = (str: string) => {
const arr = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
arr[i] = str.charCodeAt(i);
}
return arr;
}

const parsedResult = result ? JSON.stringify(result, undefined, 2) : '';

const submitForm = async (e: FormEvent) => {
e.preventDefault();
setRunning(true);
setResult(undefined);
setErr(undefined);
try {
const signature = await bb02.btcSignMessage(coin, scriptConfigWKeypath, stringToUint8Array(message));
setResult(signature);
} catch (err) {
setErr(bitbox.ensureError(err));
} finally {
setRunning(false);
}
}

return (
<div>
<h4>Sign Message</h4>
<form className="verticalForm" onSubmit={submitForm}>
<label>
<p>Coin: { coin }</p>
</label>
<label>
Simple Type
<select value={simpleType} onChange={(e: ChangeEvent<HTMLSelectElement>) => setSimpleType(e.target.value as bitbox.BtcSimpleType)}>
{simpleTypeOptions.map(option => <option key={option} value={option} disabled={false}>{option}</option>)}
</select>
</label>
<label>
Keypath
</label>
<input type="string" value={keypath} onChange={e => setKeypath(e.target.value)} />
<label>
Message
</label>
<textarea value={message} onChange={e => setMessage(e.target.value)} rows={4} cols={80} />
<button type='submit' disabled={running}>Sign message</button>
{result ? (
<div className="resultContainer">
<label>Result:
{
<textarea
rows={32}
readOnly
defaultValue={parsedResult}
/>
}
</label>
</div>
) : null }
<ShowError err={err} />
</form>
</div>
);

}

function BtcMiniscriptAddress({ bb02 }: Props) {
const [running, setRunning] = useState(false);
const [result, setResult] = useState('');
Expand Down Expand Up @@ -307,6 +388,9 @@ export function Bitcoin({ bb02 } : Props) {
<div className="action">
<BtcSignPSBT bb02={bb02} />
</div>
<div className="action">
<BtcSignMessage bb02={bb02} />
</div>
<div className="action">
<BtcMiniscriptAddress bb02={bb02} />
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/btc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ pub struct Transaction {
pub locktime: u32,
}
// See https://github.com/spesmilo/electrum/blob/84dc181b6e7bb20e88ef6b98fb8925c5f645a765/electrum/ecc.py#L521-L523
#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, serde::Serialize)]
pub struct SignMessageSignature {
pub sig: Vec<u8>,
pub recid: u8,
Expand Down Expand Up @@ -863,15 +863,15 @@ impl<R: Runtime> PairedBitBox<R> {
pub async fn btc_sign_message(
&self,
coin: pb::BtcCoin,
script_config: Option<pb::BtcScriptConfigWithKeypath>,
script_config: pb::BtcScriptConfigWithKeypath,
msg: &[u8],
) -> Result<SignMessageSignature, Error> {
self.validate_version(">=9.5.0")?;

let host_nonce = crate::antiklepto::gen_host_nonce()?;
let request = pb::BtcSignMessageRequest {
coin: coin as _,
script_config,
script_config: Some(script_config),
msg: msg.to_vec(),
host_nonce_commitment: Some(pb::AntiKleptoHostNonceCommitment {
commitment: crate::antiklepto::host_commit(&host_nonce).to_vec(),
Expand Down
15 changes: 15 additions & 0 deletions src/wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,21 @@ impl PairedBitBox {
Ok(psbt.to_string())
}

#[wasm_bindgen(js_name = btcSignMessage)]
pub async fn btc_sign_message(
&self,
coin: types::TsBtcCoin,
script_config: types::TsBtcScriptConfigWithKeypath,
msg: &[u8],
) -> Result<types::TsBtcSignMessageSignature, JavascriptError> {
let signature = self
.0
.btc_sign_message(coin.try_into()?, script_config.try_into()?, msg)
.await?;

Ok(serde_wasm_bindgen::to_value(&signature).unwrap().into())
}

/// Does this device support ETH functionality? Currently this means BitBox02 Multi.
#[wasm_bindgen(js_name = ethSupported)]
pub fn eth_supported(&self) -> bool {
Expand Down
7 changes: 7 additions & 0 deletions src/wasm/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ type BtcScriptConfigWithKeypath = {
scriptConfig: BtcScriptConfig;
keypath: Keypath;
};
type BtcSignMessageSignature = {
sig: Uint8Array,
recid: bigint,
electrumSig65: Uint8Array,
}
// nonce, gasPrice, gasLimit and value must be big-endian encoded, no trailing zeroes.
type EthTransaction = {
nonce: Uint8Array;
Expand Down Expand Up @@ -155,6 +160,8 @@ extern "C" {
pub type TsBtcScriptConfig;
#[wasm_bindgen(typescript_type = "BtcScriptConfigWithKeypath")]
pub type TsBtcScriptConfigWithKeypath;
#[wasm_bindgen(typescript_type = "BtcSignMessageSignature")]
pub type TsBtcSignMessageSignature;
#[wasm_bindgen(typescript_type = "EthTransaction")]
pub type TsEthTransaction;
#[wasm_bindgen(typescript_type = "EthSignature")]
Expand Down

0 comments on commit 29d4368

Please sign in to comment.