Re: [bitcoin-dev] New PSBT version proposal

2020-12-22 Thread fiatjaf via bitcoin-dev
Hi Andrew.

I'm just a lurker here and I have not much experience with PSBTs, but still let 
me pose this very obvious question and concern: isn't this change going to 
create a compatibility nightmare, with some software supporting version 1, 
others supporting version 2, and the ones that care enough about UX and are 
still maintained being forced to support both versions -- and for no very 
important reason except some improvements in the way data is structured?

Ultimately I don't think it should matter if some data is structured in 
not-the-best-possible way, as long as it is clear enough for the computer and 
for the libraries already written to deal with it. Backwards-compatibility and 
general interoperability is worth much more than anything else in these cases.

Also let me leave this article here, which I find very important (even if for 
some reason it ends up not being relevant to this specific case): 
http://scripting.com/2017/05/09/rulesForStandardsmakers.html

  On Tue, 22 Dec 2020 17:12:22 -0300 Andrew Chow via bitcoin-dev 
 wrote 
 > Hi All,
 > 
 > I have some updates on this after speaking with some people off-list.
 > 
 > Firstly, the version number will be set to 2. In most discussions, this 
 > proposal was being referred to as PSBT version 2, so it'll be easier and 
 > clearer to set the version number to 2.
 > 
 > For lock times, instead of a single  PSBT_IN_REQUIRED_LOCKTIME field, 
 > there will be 2 of them, one for a time based lock time, and the other 
 > for height based. These will be:
 > * PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x10
 >* Key: empty
 >* Value: 32 bit unsigned little endian integer greater than or equal 
 > to 5 representing the minimum Unix timestamp that this input 
 > requires to be set as the transaction's lock time. Must be omitted in 
 > PSBTv0, and may be omitted in PSBTv2
 > * PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x11
 >* Key: empty
 >* Value: 32 bit unsigned little endian integer less than 5 
 > representing the minimum block height that this input requires to be set 
 > as the transaction's lock time. Must be omitted in PSBTv0, and may be 
 > omitted in PSBTv2.
 > 
 > Having two lock time fields is necessary due to the behavior where all 
 > inputs must use the same type of lock time (height or time). Thus if an 
 > input requires a particular type of lock time, it must set the requisite 
 > field. Any new inputs being added must be able to accommodate all 
 > existing inputs' lock time type. This means they either must not have a 
 > lock time specified (i.e. no OP_CLTV involved), or have branches that 
 > allow the acceptance of either type. If an input has a lock time type 
 > that is incompatible with the rest of the transaction, it must not be added.
 > 
 > PSBT_GLOBAL_PREFERRED_LOCKTIME is changed to purely be the fallback 
 > option if no input lock time fields are present. If there are input lock 
 > times, all lock time calculations must ignore it.
 > 
 > Any role which does lock time calculation will first check if there are 
 > input lock time fields. If there are not, it must then check for a 
 > PSBT_GLOBAL_PREFERRED_LOCKTIME. If this field exists, its value is the 
 > transaction's lock time. If it does not, the lock time is 0. If there 
 > are input lock time fields, it must choose the type which does not 
 > invalidate any inputs. The lock time is then determined to be the 
 > maximum value of all of the lock time fields for the chosen type.
 > 
 > 
 > Additionally, I would like to add a new global field:
 > * PSBT_GLOBAL_UNDER_CONSTRUCTION = 0x05
 >* Key: empty
 >* Value: A single byte as a boolean. 0 for False, 1 for True. All 
 > other values ore prohibited. Must be omitted for PSBTv0, may be omitted 
 > in PSBTv2.
 > 
 > PSBT_GLOBAL_UNDER_CONSTRUCTION is used to signal whether inputs and 
 > outputs can be added to the PSBT. This flag may be set to True when 
 > inputs and outputs are being updated, signed, and finalized. However 
 > care must be taken when there are existing signatures. If this field is 
 > omitted or set to False, no further inputs and outputs may be added to 
 > the PSBT.
 > 
 > Several rules must be followed to ensure that adding additional inputs 
 > and outputs will not invalidate existing signatures. First, an input or 
 > output adder must check for any existing signatures in all of the other 
 > inputs. If there are none, the input or output may be added in any 
 > position. If there are one or more signatures, each signature's sighash 
 > type must be examined. Inputs may only be added if all existing 
 > signatures use SIGHASH_ANYONECANPAY. Outputs may only be added if all 
 > existing signatures use SIGHASH_NONE. If an input has a signature using 
 > SIGHASH_SINGLE, the same number of inputs and outputs must be added 
 > before that input and it's corresponding output. For all other sighash 
 > types (i.e. SIGHASH_ALL and any future sighash types), no inputs or 
 

Re: [bitcoin-dev] BIP Proposal: Wallet Interface

2020-12-22 Thread Luke Dashjr via bitcoin-dev
1) People should not be encouraged to write or use web browsers for their 
wallet.
2) You may want to look over earlier work in this area.

On Tuesday 22 December 2020 14:43:11 monokh via bitcoin-dev wrote:
> Hi
>
> This is a first draft of a BIP we intend to submit. The main intention is
> to define a simple interface that wallets and applications can agree on
> that would cover the vast majority of use cases. This can enable writing
> bitcoin applications (e.g. time lock, multi sig) on the web that can be
> seamlessly used with any compatible wallets. We have implementations of
> such examples but I don't want to turn this thread into a promotion and
> rather focus on the spec.
>
> Appreciate input from the list. Please share if there are existing efforts,
> relevant specs or use cases.
>
> --
>
> A wallet interface specification for bitcoin applications
>
> ## Abstract
>
> This BIP describes an API for Bitcoin wallets and applications as a
> standard.
>
> ## Summary
>
> Bitcoin wallets should expose their address derivation and signing
> functions to external applications. The interface would be expressed as
> follows in javascript:
>
> ```
> {
> // Wallet Metadata
> wallet: {
> name: 'Bitcoin Core'
> },
>
> // Request access to the wallet for the current host
> async enable: (),
>
> // Request addresses and signatures from wallet
> async request ({ method, params })
> }
> ```
>
> In the web context the interface could be exposed at the top level of a
> webpage, for example under `window.bitcoin`. However this spec does not
> intend to define any standards for how and where the interfaces should be
> exposed.
>
> ## Motivation
>
> Due to the seldom available APIs exposed by wallets, applications (web or
> otherwise) are limited in how they are able to interact. Generally only
> simple sends have been available. A more robust API that introduces other
> requests will promote richer Bitcoin applications.
>
> Additionally, wallet APIs have frequently included inconsistencies in their
> interfaces and behaviour. This has required applications to build and
> maintain a separate client for each wallet, increasing the risk of bugs and
> unintended behaviour as well as being a limiting factor for the adoption of
> usable bitcoin applications.
>
> With a standardised wallet API:
>
> - Wallets have a clear API to implement
> - Applications have a clear expectation of wallet interface and behaviour
> - Applications become agnostic to the wallet specifics, increasing choice
> for users
>
> If more wallets implement the specification, applications will be developed
> more confidently by benefiting from the wallet interoperability. This
> creates a positive feedback loop.
>
> ## Specification
>
> For simplicity, the interface is defined in the context of web applications
> running in the browser (JS) however, they are simple enough to be easily
> implemented in other contexts.
>
> ### General Rules
>
> - For sensitive functions (e.g. signing), wallet software should always
> prompt the user for confirmation
>
> ### Types
>
> **UserDeniedError**
> An error type indicating that the application's request has been denied by
> the user
> Type: Error
>
> **Hex**
> Type: String
> Example:
> `"000a24677957d1e50d70e67c513d220dbe8868c4c3aefc08"`
>
> **Address**
> Address details
> Type: Object
> Example:
>
> ```
> {
> "address": "bc1qn0fqlzamcfuahq6xuujrq08ex7e26agt20gexs",
> "publicKey":
> "02ad58c0dced71a236f4073c3b6f0ee27dde6fe96978e9a9c9500172e3f1886e5a",
> "derivationPath": "84'/1'/0'/0/0"
> }
> ```
>
> ### API
>
> The wallet must implement the following methods.
>
> **enable**
>
> The enable call prompts the user for access to the wallet.
>
> If successful, it resolves to an address (`**Address**` type) of the
> wallet. Typically the first external address to be used as an identity.
>
> **`UserDeniedError`** will be thrown if the request is rejected.
>
> **request**
>
> The request method must take one parameter in the following format:
>
> ```
> {
> "method": "wallet_methodName",
> "params": ["foo", "bar", "baz"]
> }
> ```
>
> For a list of mandatory methods see Table
>
> The wallet should reject request calls unless `enable` has been resolved.
>
> Sensitive requests that involve signing should always prompt the user for
> confirmation
>
> On success the request should resolve to the response as defined in the
> method table.
>
> **`UserDeniedError`** will be thrown if the request is rejected.
>
> **Mandatory methods**
>
> method: `wallet_getAddresses` params: [`index = 0, numAddresses = 1, change
> = false`]
> return: `[ Address ]`
> error: UserDeniedError
>
> method: `wallet_signMessage` params: `[ message, address ]`
> return: Signature `Hex`
> error: UserDeniedError
>
> method: `wallet_signPSBT` params: `[ [psbtBase64, inputIndex, address] ]`
> return: `psbtBase64`
> error: UserDeniedError
>
> method: `wallet_getConnectedNetwork` params: `[]`
> return: Network object 

Re: [bitcoin-dev] New PSBT version proposal

2020-12-22 Thread Andrew Chow via bitcoin-dev
Hi All,

I have some updates on this after speaking with some people off-list.

Firstly, the version number will be set to 2. In most discussions, this 
proposal was being referred to as PSBT version 2, so it'll be easier and 
clearer to set the version number to 2.

For lock times, instead of a single  PSBT_IN_REQUIRED_LOCKTIME field, 
there will be 2 of them, one for a time based lock time, and the other 
for height based. These will be:
* PSBT_IN_REQUIRED_TIME_LOCKTIME = 0x10
   * Key: empty
   * Value: 32 bit unsigned little endian integer greater than or equal 
to 5 representing the minimum Unix timestamp that this input 
requires to be set as the transaction's lock time. Must be omitted in 
PSBTv0, and may be omitted in PSBTv2
* PSBT_IN_REQUIRED_HEIGHT_LOCKTIME = 0x11
   * Key: empty
   * Value: 32 bit unsigned little endian integer less than 5 
representing the minimum block height that this input requires to be set 
as the transaction's lock time. Must be omitted in PSBTv0, and may be 
omitted in PSBTv2.

Having two lock time fields is necessary due to the behavior where all 
inputs must use the same type of lock time (height or time). Thus if an 
input requires a particular type of lock time, it must set the requisite 
field. Any new inputs being added must be able to accommodate all 
existing inputs' lock time type. This means they either must not have a 
lock time specified (i.e. no OP_CLTV involved), or have branches that 
allow the acceptance of either type. If an input has a lock time type 
that is incompatible with the rest of the transaction, it must not be added.

PSBT_GLOBAL_PREFERRED_LOCKTIME is changed to purely be the fallback 
option if no input lock time fields are present. If there are input lock 
times, all lock time calculations must ignore it.

Any role which does lock time calculation will first check if there are 
input lock time fields. If there are not, it must then check for a 
PSBT_GLOBAL_PREFERRED_LOCKTIME. If this field exists, its value is the 
transaction's lock time. If it does not, the lock time is 0. If there 
are input lock time fields, it must choose the type which does not 
invalidate any inputs. The lock time is then determined to be the 
maximum value of all of the lock time fields for the chosen type.


Additionally, I would like to add a new global field:
* PSBT_GLOBAL_UNDER_CONSTRUCTION = 0x05
   * Key: empty
   * Value: A single byte as a boolean. 0 for False, 1 for True. All 
other values ore prohibited. Must be omitted for PSBTv0, may be omitted 
in PSBTv2.

PSBT_GLOBAL_UNDER_CONSTRUCTION is used to signal whether inputs and 
outputs can be added to the PSBT. This flag may be set to True when 
inputs and outputs are being updated, signed, and finalized. However 
care must be taken when there are existing signatures. If this field is 
omitted or set to False, no further inputs and outputs may be added to 
the PSBT.

Several rules must be followed to ensure that adding additional inputs 
and outputs will not invalidate existing signatures. First, an input or 
output adder must check for any existing signatures in all of the other 
inputs. If there are none, the input or output may be added in any 
position. If there are one or more signatures, each signature's sighash 
type must be examined. Inputs may only be added if all existing 
signatures use SIGHASH_ANYONECANPAY. Outputs may only be added if all 
existing signatures use SIGHASH_NONE. If an input has a signature using 
SIGHASH_SINGLE, the same number of inputs and outputs must be added 
before that input and it's corresponding output. For all other sighash 
types (i.e. SIGHASH_ALL and any future sighash types), no inputs or 
outputs may be added to the PSBT. Specific exceptions can be made in the 
future for additional sighash types.

Furthermore, these newly added inputs must follow additional lock time 
rules. Because all signatures, regardless of sighash type, sign the 
transaction lock time, newly added inputs when there are existing 
signatures must have the same type of lock time used in the transaction, 
and must be less than or equal to the transaction lock time. It must not 
cause the transaction lock time to change, otherwise the signatures will 
be invalidated.


Lastly, to uniquely identify transactions for combiners, a txid can be 
computed from the information present in the PSBT. Internally, combiners 
can create an unsigned transaction given the transaction version, the 
input prevouts, the outputs, and the computed locktime. This can then be 
used to calculate a txid and thus used as a way to identify PSBTs. 
Combiners will need to do this for all version 2 PSBTs in order to avoid 
combining distinct transactions.


Andrew Chow

On 12/9/20 5:25 PM, Andrew Chow wrote:
> Hi All,
>
> I would like to propose a new PSBT version that addresses a few
> deficiencies in the current PSBT v0. As this will be backwards
> incompatible, a new PSBT version will be used, v1.
>
> The 

[bitcoin-dev] BIP Proposal: Wallet Interface

2020-12-22 Thread monokh via bitcoin-dev
Hi

This is a first draft of a BIP we intend to submit. The main intention is
to define a simple interface that wallets and applications can agree on
that would cover the vast majority of use cases. This can enable writing
bitcoin applications (e.g. time lock, multi sig) on the web that can be
seamlessly used with any compatible wallets. We have implementations of
such examples but I don't want to turn this thread into a promotion and
rather focus on the spec.

Appreciate input from the list. Please share if there are existing efforts,
relevant specs or use cases.

--

A wallet interface specification for bitcoin applications

## Abstract

This BIP describes an API for Bitcoin wallets and applications as a
standard.

## Summary

Bitcoin wallets should expose their address derivation and signing
functions to external applications. The interface would be expressed as
follows in javascript:

```
{
// Wallet Metadata
wallet: {
name: 'Bitcoin Core'
},

// Request access to the wallet for the current host
async enable: (),

// Request addresses and signatures from wallet
async request ({ method, params })
}
```

In the web context the interface could be exposed at the top level of a
webpage, for example under `window.bitcoin`. However this spec does not
intend to define any standards for how and where the interfaces should be
exposed.

## Motivation

Due to the seldom available APIs exposed by wallets, applications (web or
otherwise) are limited in how they are able to interact. Generally only
simple sends have been available. A more robust API that introduces other
requests will promote richer Bitcoin applications.

Additionally, wallet APIs have frequently included inconsistencies in their
interfaces and behaviour. This has required applications to build and
maintain a separate client for each wallet, increasing the risk of bugs and
unintended behaviour as well as being a limiting factor for the adoption of
usable bitcoin applications.

With a standardised wallet API:

- Wallets have a clear API to implement
- Applications have a clear expectation of wallet interface and behaviour
- Applications become agnostic to the wallet specifics, increasing choice
for users

If more wallets implement the specification, applications will be developed
more confidently by benefiting from the wallet interoperability. This
creates a positive feedback loop.

## Specification

For simplicity, the interface is defined in the context of web applications
running in the browser (JS) however, they are simple enough to be easily
implemented in other contexts.

### General Rules

- For sensitive functions (e.g. signing), wallet software should always
prompt the user for confirmation

### Types

**UserDeniedError**
An error type indicating that the application's request has been denied by
the user
Type: Error

**Hex**
Type: String
Example:
`"000a24677957d1e50d70e67c513d220dbe8868c4c3aefc08"`

**Address**
Address details
Type: Object
Example:

```
{
"address": "bc1qn0fqlzamcfuahq6xuujrq08ex7e26agt20gexs",
"publicKey":
"02ad58c0dced71a236f4073c3b6f0ee27dde6fe96978e9a9c9500172e3f1886e5a",
"derivationPath": "84'/1'/0'/0/0"
}
```

### API

The wallet must implement the following methods.

**enable**

The enable call prompts the user for access to the wallet.

If successful, it resolves to an address (`**Address**` type) of the
wallet. Typically the first external address to be used as an identity.

**`UserDeniedError`** will be thrown if the request is rejected.

**request**

The request method must take one parameter in the following format:

```
{
"method": "wallet_methodName",
"params": ["foo", "bar", "baz"]
}
```

For a list of mandatory methods see Table

The wallet should reject request calls unless `enable` has been resolved.

Sensitive requests that involve signing should always prompt the user for
confirmation

On success the request should resolve to the response as defined in the
method table.

**`UserDeniedError`** will be thrown if the request is rejected.

**Mandatory methods**

method: `wallet_getAddresses` params: [`index = 0, numAddresses = 1, change
= false`]
return: `[ Address ]`
error: UserDeniedError

method: `wallet_signMessage` params: `[ message, address ]`
return: Signature `Hex`
error: UserDeniedError

method: `wallet_signPSBT` params: `[ [psbtBase64, inputIndex, address] ]`
return: `psbtBase64`
error: UserDeniedError

method: `wallet_getConnectedNetwork` params: `[]`
return: Network object `mainnet` | `testnet` | `regetst`
error: UserDeniedError

## Rationale

The purpose of the API is to expose a set of commonly used wallet
operations. In addition, it should be flexible enough to serve for other
requests such as node RPC calls.

**Why is there a singular request call instead of named methods?**
The transport layer for the requests cannot be assumed, therefore it is
much more flexible to instead define an abstract format.

**Why are the mandatory methods so primitive?