RESTful Bitcoin Payment Channel Protocol (v2)

Base URL: /v2, Version: 2.3.0

A Bitcoin payment channel enables sending bitcoins between two parties instantly, securely and without fees. The intended use is consumer-to-merchant payments, allowing a consumer to make many small payments to a merchant - with whom the consumer has an open payment channel - while only paying the Bitcoin transaction fee once, when the channel is closed.

An arbitrary number of payments can be made over the course of, say, one week, and at the end of this week the settlement transaction is published, thus reducing the Bitcoin transaction fee to something that has to be paid every week, rather every time a transaction is made.

The payment server speaking this protocol is the recipient of value. Arbitrary application data can be included with the payment by the client, and returned in response to a payment by the server.

To start out, the client fetches the server's FundingInfo, using the "/funding/[...]/info" endpoint. The client then constructs a CLTV (BIP65) redeemScript, as defined in the section Two-factor wallets in BIP-65[1] , using 'server_pubkey' (from FundingInfo) plus the client's supplied public key and expiration time. From this redeemScript a P2SH channel funding address is derived, and the client will confirm that this agrees with the server-derived 'funding_address_copy' (in FundingInfo), before publishing a Bitcoin transaction that pays to it. This transaction we call the "funding transaction", and the output in this transaction, that pays to the channel funding address, we call the "funding output".

In order to begin paying the server, the client then constructs a Bitcoin transaction which spends the funding output. We call this the "payment transaction". This Bitcoin transaction redeems the outpoint specified by 'funding_txid' and 'funding_vout' (the funding output), and has a single output that pays 'change_value' to 'change_address'. By decrementing the 'change_value' for this transaction, signing it, and transmitting (at least) the new signature and change value to the server, the client can send payments to the server.

The PaymentData object contains all the information necessary to construct the payment transaction. Importantly, the client must sign the payment transaction using the SIG_SINGLE|ANYONECANPAY sighash flag, thus allowing the server to add its own output to the client-signed transaction afterwards.

A detailed explanation, of how the payment transaction is constructed, can be found in the JavaScript client library for this protocol, by looking at the createPayment function: https://github.com/runeksvendsen/paychanjs-client/blob/master/paychan-core.js#L100

[1] https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki#Twofactor_wallets

Schemes: https

Summary

Tag: Channel setup

Operation Description
GET /funding/{exp_time}/{client_pubkey}/info

Get funding info

POST /channels/{funding_txid}/{funding_vout}

Create new channel

Tag: Channel operation

Operation Description
PUT /channels/{funding_txid}/{funding_vout}

Send value

PUT /channels/{funding_txid}/{funding_vout}/close

Close channel

Paths

Create new channel

POST /channels/{funding_txid}/{funding_vout}

Tags: Channel setup

After publishing the funding Bitcoin transaction, and waiting for the specified number of confirmations, the client will POST a payment, paying the server's specified channel open price, to this URL. Subsequent channel payments will be PUT on this same URL.

For information on how to create a payment, see documentation on the PUT request (on this resource) and the PaymentData object.

application/json

funding_txid

The Bitcoin transaction ID part of the outpoint in the Blockchain which holds the client's channel balance.

path string #/parameters/fundingSourceTxIdParam
funding_vout

The output index part of the outpoint in the Blockchain which holds the client's channel balance.

path integer #/parameters/fundingSourceVoutParam
secret

SHA256 hash of the opening channel payment's signature data (signature_data in PaymentData), hex-encoded. This acts as a secret known only to the client and server, hereby preventing third parties from figuring out payment resource URLs by looking through the blockchain. This acts as a denial-of-service protection for the server operator. A 404 response should be returned in case the server receives a request with an incorrect client secret, but with otherwise correct data. Also, the server software should be designed in such a way that no difference in response time can be measured between a "genuine" 404 response, and a 404 response that results only from an incorrect secret.

query string #/parameters/clientServerSecret
chan_open_body

Channel-open payment data

body object #/parameters/chanOpenBody

application/json

201 Created

Channel created

Location

URL of the newly opened channel

string (uri)
400 Bad Request

Invalid parameter

409 Conflict

Channel already exists

Location

URL of the already open channel

string (uri)
Send value

PUT /channels/{funding_txid}/{funding_vout}

Tags: Channel operation

Make payment over an existing payment channel.

To pay the server, the client will create a new PaymentData object with the source of funding set to the outpoint specified by the 'funding_txid' and funding_vout parameters. The client change amount is decremented by the desired payment amount, and the change address is set to the channel funding address (in order to allow the server to free the received funds without involvement from the client). Only 'change_value' and 'signature_data' change for new payments.

application/json

funding_txid

The Bitcoin transaction ID part of the outpoint in the Blockchain which holds the client's channel balance.

path string #/parameters/fundingSourceTxIdParam
funding_vout

The output index part of the outpoint in the Blockchain which holds the client's channel balance.

path integer #/parameters/fundingSourceVoutParam
secret

SHA256 hash of the opening channel payment's signature data (signature_data in PaymentData), hex-encoded. This acts as a secret known only to the client and server, hereby preventing third parties from figuring out payment resource URLs by looking through the blockchain. This acts as a denial-of-service protection for the server operator. A 404 response should be returned in case the server receives a request with an incorrect client secret, but with otherwise correct data. Also, the server software should be designed in such a way that no difference in response time can be measured between a "genuine" 404 response, and a 404 response that results only from an incorrect secret.

query string #/parameters/clientServerSecret
chan_pay_body

Value-send payment data

body object #/parameters/chanPayBody

application/json

200 OK

Value received

318

The payment resource has moved permanently. Perform this request, and all future requests, using the resource specified in the Location header (same as 308 but request body data needs to be updated to fit new resource).

Location

New payment resource location

string (uri)
400 Bad Request

Invalid parameter

410 Gone

The channel is in the process of being closed. Performing a DELETE request on the resource in a few seconds should return information about the closed channel.

Close channel

PUT /channels/{funding_txid}/{funding_vout}/close

Tags: Channel operation

In order to enable the server to return unsent funds to the client, the client must provide a payment of zero value with the change_address field set according to the client's wish (as opposed to a payment where change_address always equals the channel funding address). After a successful request, the settling transaction is published to the Bitcoin network, and the PaymentResult response will include its transaction ID.

application/json

funding_txid

The Bitcoin transaction ID part of the outpoint in the Blockchain which holds the client's channel balance.

path string #/parameters/fundingSourceTxIdParam
funding_vout

The output index part of the outpoint in the Blockchain which holds the client's channel balance.

path integer #/parameters/fundingSourceVoutParam
secret

SHA256 hash of the opening channel payment's signature data (signature_data in PaymentData), hex-encoded. This acts as a secret known only to the client and server, hereby preventing third parties from figuring out payment resource URLs by looking through the blockchain. This acts as a denial-of-service protection for the server operator. A 404 response should be returned in case the server receives a request with an incorrect client secret, but with otherwise correct data. Also, the server software should be designed in such a way that no difference in response time can be measured between a "genuine" 404 response, and a 404 response that results only from an incorrect secret.

query string #/parameters/clientServerSecret
chan_pay_body

Value-send payment data

body object #/parameters/chanPayBody

application/json

200 OK

Channel closed, funds settled. The settling transaction has been published to the Bitcoin network.

400 Bad Request

Invalid parameter

Get funding info

GET /funding/{exp_time}/{client_pubkey}/info

Tags: Channel setup

Before opening a payment channel with the server, the client must first acquire the server public key, in order to derive a funding address for the channel.

The client will first calculate the funding address, confirm that it matches the server's, then pay to the funding address, and wait until the funding transaction has the server-specified number of confirmations (funding_tx_min_conf).

After this, the client will create a new payment of value equal to the server-specified (open_price), and POST this payment to the channel URI to open the channel. Further payments are made though a PUT request on the same URI.

exp_time

Expiration date/time for the channel (Unix timestamp)

path integer (uint32) #/parameters/expTimeParam
client_pubkey

Client/value sender public key. Hex-encoded, compressed Secp256k1 pubkey, 33 bytes.

path string #/parameters/clientPubKeyParam

application/json application/bitcoin-paymentrequest

200 OK

Proceed with funding

400 Bad Request

Invalid parameter

Parameter definitions

expTimeParam exp_time

Expiration date/time for the channel (Unix timestamp)

path integer (uint32)
clientPubKeyParam client_pubkey

Client/value sender public key. Hex-encoded, compressed Secp256k1 pubkey, 33 bytes.

path string
fundingSourceTxIdParam funding_txid

The Bitcoin transaction ID part of the outpoint in the Blockchain which holds the client's channel balance.

path string
fundingSourceVoutParam funding_vout

The output index part of the outpoint in the Blockchain which holds the client's channel balance.

path integer
clientServerSecret secret

SHA256 hash of the opening channel payment's signature data (signature_data in PaymentData), hex-encoded. This acts as a secret known only to the client and server, hereby preventing third parties from figuring out payment resource URLs by looking through the blockchain. This acts as a denial-of-service protection for the server operator. A 404 response should be returned in case the server receives a request with an incorrect client secret, but with otherwise correct data. Also, the server software should be designed in such a way that no difference in response time can be measured between a "genuine" 404 response, and a 404 response that results only from an incorrect secret.

query string
chanOpenBody chan_open_body

Channel-open payment data

body object
chanPayBody chan_pay_body

Value-send payment data

body object

Schema definitions

CompactPaymentData: object

Same as PaymentData, but with everything but 'signature_data' and 'change_value' stripped away. This is the minimum amount of information needed for the server to receive value.

signature_data: string

DER-encoded ECDSA signature (in hex), including signature hash flag. This is a SIGHASH_SINGLE|ANYONECANPAY or SIGHASH_NONE|ANYONECANPAY signature over the the "payment transaction", which is a Bitcoin transaction that: redeems the outpoint specified by 'funding_txid' and 'funding_vout' using the redeem script defined in 'redeem_script', with an output which sends 'change_value' to 'change_address'.

"3044022[...]4fd983 (~72 bytes in total)"
                                                        
change_value: integer (uint64)

The value sent back to the client in the payment transaction. The total amount transferred to the server is this amount subtracted from the value sent to the channel funding address.

1000000
                                                        

FundingInfo: object

server_pubkey: string

Server/value receiver public key. Hex-encoded, compressed Secp256k1 pubkey, 33 bytes.

"029b5549e8cac42d27051956925d8176408b2183ba357850f58320ad5876b9c13f"
                                                        
dust_limit: integer (uint64)

(Satoshis) The server will not accept payments where the client change amount is less than this amount. This "dust limit" is necessary in order to avoid producing a settlement transaction that will not circulate in the Bitcoin P2P network because it contains an output of value below the so-called "dust limit".

500
                                                        
funding_address_copy: string

Server derived channel funding address. The client will confirm that its own derived funding address matches this one, before paying to it.

"2NCTirSGjFM8T7hUow3AcfyFaw1N1APnYuP"
                                                        
open_price: integer (uint64) , { x ∈ ℤ | x ≥ 0 }

Price (in satoshis) for opening a channel with the given {exp_time}. This amount is paid in the initial channel payment when opening a new channel. The server should choose a price that is greater than or equal to the dust limit.

25000
                                                        
funding_tx_min_conf: integer (int32) , { x ∈ ℤ | x ≥ 0 }

The client must wait for the funding transaction to have this many confirmations before opening the channel.

6
                                                        
settlement_period_hours: integer , { x ∈ ℤ | x ≥ 0 }

The server reserves the right to close the payment channel this many hours before the specified expiration date. The server hasn't received any actual value until it publishes a payment transaction to the Bitcoin network, so it needs a window of time in which the client can no longer send payments over the channel, while the channel refund transaction hasn't become valid yet.

12
                                                        
min_duration_hours: integer , { x ∈ ℤ | x ≥ 0 }

Payment channel minimum duration, in hours. The client-chosen channel expiration time must be at least this figure plus 'settlement_period_hours' hours into the future.

48
                                                        

Payment: object

Used when sending value over an open payment channel. Contains CompactPaymentData plus application data.

payment_data: object

Payment data for an already-open channel

application_data: string

Arbitrary application data. Used by the application protocol that's using this payment channel protocol to transmit value. For the opening channel payment, this field MUST be equal to the empty string.

"{ order_ref : 19834938743 }"
                                                        

PaymentData: object

Used when creating a new payment channel. Contains all information necessary for the server to construct the channel payment transaction. A payment comprises a signature over the payment transaction with a decremented client change value. The payment Bitcoin transaction redeems the outpoint specified by 'funding_txid' and 'funding_vout' (a P2SH output governed by 'redeem_script'), and pays 'change_value' to 'change_address'.

redeem_script: string

Hex-encoded data. The funds sent to the funding address are bound by this contract (Bitcoin script). Used to construct the payment transaction. A hash of this script is the channel funding address (a P2SH address).

"63210225b3aaf58992a8cc909522c2ec859ef218fd29fda0a6723cfb4e0529f80cc8f3ad6704002f6859b175682103da3afe4f58992a8cc909522c2ec859ef218fd92fda0a67c23fb40e0303030405ac"
                                                        
funding_txid: string

The transaction ID of the Bitcoin transaction paying to the channel funding address.

"88173df15ec17490288cabaa9a0becfdef3614d9526eec16f670886d7d229301"
                                                        
funding_vout: integer (uint32)

The output index/"vout" of the output (in the transaction) payingto the channel funding address.

1
                                                        
signature_data: string

DER-encoded ECDSA signature (in hex), including signature hash flag. This is a SIGHASH_SINGLE|ANYONECANPAY or SIGHASH_NONE|ANYONECANPAY signature over the the "payment transaction", which is a Bitcoin transaction that: redeems the outpoint specified by 'funding_txid' and 'funding_vout' using the redeem script defined in 'redeem_script', with an output which sends 'change_value' to 'change_address'.

"3044022[...]4fd983 (~72 bytes in total)"
                                                        
change_value: integer (uint64)

The value sent back to the client in the payment transaction. The total amount transferred to the server is this amount subtracted from the value sent to the channel funding address.

1000000
                                                        
change_address: string

The client change address as used in the only output of the payment transaction (equal to the channel funding address, except for the payment required to close the channel, in which the client can specify its desired refund address).

"2NCTirSGjFM8T7hUow3AcfyFaw1N1APnYuP"
                                                        

PaymentResult: object

channel_status: string

Equal to "open" if the channel is still open, otherwise "closed". The channel is automatically closed when there is no value left to send. If a payment sends all remaining channel value to the server, the server will close the channel and set this field to "closed".

"open"
                                                        
channel_value_left: integer , { x ∈ ℤ | x ≥ 0 }

Remaining channel value. This is the amount that the client/sender would receive if the channel was closed now.

1700000
                                                        
value_received: integer , { x ∈ ℤ | x ≥ 0 }

Value of the payment that was just received. This is the additional value assigned to the receiver/server with this payment.

1000
                                                        
settlement_txid: string

If channel_status equals "closed": the transaction ID of the Bitcoin transaction which settles the channel; otherwise the empty string.

application_data: string

Optional application data (may be the empty string). The application, that is using this payment channel protocol to transmit value, may wish to include some application-specific data in response to a payment. This field is for that. The format is left entirely up to the application.

"{ 'secret_code' : '2cd3b27536165ee6f110857c483509cb' }"