Skip to content

Commit

Permalink
miniscript: add proto messages
Browse files Browse the repository at this point in the history
We will support miniscript as part of output descriptors.

Descriptors are an expression language to specify Bitcoin outputs. For
example, `wsh(multi(2,<pubkey1>,<pubkey2>,<pubkey3>))` is a 2-of-3
multisig wrapped in a P2WSH (pay-to-witness-script-hash) output.
Descriptors specification: https://github.com/bitcoin/bitcoin/blob/8f402710371a40c5777dc3f9c4ba6ca8505a2f90/doc/descriptors.md

In fragments wrapping SCRIPT expressions, SCRIPT can also be a
miniscript expression, for example: `wsh(or_b(pk(<pubkey1>),s:pk(<pubkey2>)))`.

With hardware signers, we want to use xpubs with derivations instead
of raw pubkeys, and also have a shorter representation than inlining
the xpubs for readability. That is why we will follow the 'Wallet
Policies for Descriptor Wallets' proposal specied here:

https://github.com/bigspider/bips/blob/bip-wallet-policies/bip-wallet-policies.mediawiki (bitcoin/bips#1389).

The above example then become `wsh(or_b(pk(@0/**),s:pk(@1/**)))`. The
`@NUM` references a key provided in the keys list.

For the policy with the keys, one can then derive pkScripts for
receive and change addresses and use these to create addresses.
  • Loading branch information
benma committed Jun 29, 2023
1 parent 26dae59 commit 5196443
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 61 deletions.
8 changes: 8 additions & 0 deletions messages/btc.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,17 @@ message BTCScriptConfig {
ScriptType script_type = 4;
}

// A policy as specified by 'Wallet policies':
// https://github.com/bitcoin/bips/pull/1389
message Policy {
string policy = 1;
repeated KeyOriginInfo keys = 2;
}

oneof config {
SimpleType simple_type = 1;
Multisig multisig = 2;
Policy policy = 3;
}
}

Expand Down
6 changes: 6 additions & 0 deletions messages/common.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,9 @@ message XPub {
message Keypath {
repeated uint32 keypath = 1;
}

message KeyOriginInfo {
bytes root_fingerprint = 1;
repeated uint32 keypath = 2;
XPub xpub = 3;
}
114 changes: 58 additions & 56 deletions py/bitbox02/bitbox02/communication/generated/btc_pb2.py

Large diffs are not rendered by default.

27 changes: 24 additions & 3 deletions py/bitbox02/bitbox02/communication/generated/btc_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,40 @@ class BTCScriptConfig(google.protobuf.message.Message):
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["our_xpub_index",b"our_xpub_index","script_type",b"script_type","threshold",b"threshold","xpubs",b"xpubs"]) -> None: ...

class Policy(google.protobuf.message.Message):
"""A policy as specified by 'Wallet policies':
https://github.com/bitcoin/bips/pull/1389
"""
DESCRIPTOR: google.protobuf.descriptor.Descriptor
POLICY_FIELD_NUMBER: builtins.int
KEYS_FIELD_NUMBER: builtins.int
policy: typing.Text
@property
def keys(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[common_pb2.KeyOriginInfo]: ...
def __init__(self,
*,
policy: typing.Text = ...,
keys: typing.Optional[typing.Iterable[common_pb2.KeyOriginInfo]] = ...,
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["keys",b"keys","policy",b"policy"]) -> None: ...

SIMPLE_TYPE_FIELD_NUMBER: builtins.int
MULTISIG_FIELD_NUMBER: builtins.int
POLICY_FIELD_NUMBER: builtins.int
simple_type: global___BTCScriptConfig.SimpleType.ValueType
@property
def multisig(self) -> global___BTCScriptConfig.Multisig: ...
@property
def policy(self) -> global___BTCScriptConfig.Policy: ...
def __init__(self,
*,
simple_type: global___BTCScriptConfig.SimpleType.ValueType = ...,
multisig: typing.Optional[global___BTCScriptConfig.Multisig] = ...,
policy: typing.Optional[global___BTCScriptConfig.Policy] = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","simple_type",b"simple_type"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","simple_type",b"simple_type"]) -> None: ...
def WhichOneof(self, oneof_group: typing_extensions.Literal["config",b"config"]) -> typing.Optional[typing_extensions.Literal["simple_type","multisig"]]: ...
def HasField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","policy",b"policy","simple_type",b"simple_type"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["config",b"config","multisig",b"multisig","policy",b"policy","simple_type",b"simple_type"]) -> None: ...
def WhichOneof(self, oneof_group: typing_extensions.Literal["config",b"config"]) -> typing.Optional[typing_extensions.Literal["simple_type","multisig","policy"]]: ...
global___BTCScriptConfig = BTCScriptConfig

class BTCPubRequest(google.protobuf.message.Message):
Expand Down
4 changes: 3 additions & 1 deletion py/bitbox02/bitbox02/communication/generated/common_pb2.py

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

20 changes: 20 additions & 0 deletions py/bitbox02/bitbox02/communication/generated/common_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,23 @@ class Keypath(google.protobuf.message.Message):
) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["keypath",b"keypath"]) -> None: ...
global___Keypath = Keypath

class KeyOriginInfo(google.protobuf.message.Message):
DESCRIPTOR: google.protobuf.descriptor.Descriptor
ROOT_FINGERPRINT_FIELD_NUMBER: builtins.int
KEYPATH_FIELD_NUMBER: builtins.int
XPUB_FIELD_NUMBER: builtins.int
root_fingerprint: builtins.bytes
@property
def keypath(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.int]: ...
@property
def xpub(self) -> global___XPub: ...
def __init__(self,
*,
root_fingerprint: builtins.bytes = ...,
keypath: typing.Optional[typing.Iterable[builtins.int]] = ...,
xpub: typing.Optional[global___XPub] = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["xpub",b"xpub"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["keypath",b"keypath","root_fingerprint",b"root_fingerprint","xpub",b"xpub"]) -> None: ...
global___KeyOriginInfo = KeyOriginInfo
24 changes: 23 additions & 1 deletion src/rust/bitbox02-rust/src/shiftcrypto.bitbox02.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ pub struct Keypath {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct KeyOriginInfo {
#[prost(bytes = "vec", tag = "1")]
pub root_fingerprint: ::prost::alloc::vec::Vec<u8>,
#[prost(uint32, repeated, tag = "2")]
pub keypath: ::prost::alloc::vec::Vec<u32>,
#[prost(message, optional, tag = "3")]
pub xpub: ::core::option::Option<XPub>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct CheckBackupRequest {
#[prost(bool, tag = "1")]
pub silent: bool,
Expand Down Expand Up @@ -203,7 +213,7 @@ pub struct AntiKleptoSignatureRequest {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BtcScriptConfig {
#[prost(oneof = "btc_script_config::Config", tags = "1, 2")]
#[prost(oneof = "btc_script_config::Config", tags = "1, 2, 3")]
pub config: ::core::option::Option<btc_script_config::Config>,
}
/// Nested message and enum types in `BTCScriptConfig`.
Expand Down Expand Up @@ -265,6 +275,16 @@ pub mod btc_script_config {
}
}
}
/// A policy as specified by 'Wallet policies':
/// <https://github.com/bitcoin/bips/pull/1389>
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Policy {
#[prost(string, tag = "1")]
pub policy: ::prost::alloc::string::String,
#[prost(message, repeated, tag = "2")]
pub keys: ::prost::alloc::vec::Vec<super::KeyOriginInfo>,
}
/// SimpleType is a "simple" script: one public key, no additional inputs.
#[derive(
Clone,
Expand Down Expand Up @@ -312,6 +332,8 @@ pub mod btc_script_config {
SimpleType(i32),
#[prost(message, tag = "2")]
Multisig(Multisig),
#[prost(message, tag = "3")]
Policy(Policy),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
Expand Down

0 comments on commit 5196443

Please sign in to comment.