Skip to content

Instantly share code, notes, and snippets.

@jgarzik
Last active August 29, 2015 13:57
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgarzik/9494153 to your computer and use it in GitHub Desktop.
Save jgarzik/9494153 to your computer and use it in GitHub Desktop.
Payment channel JSON-RPC protocol

This protocol describes a simple payment channel protocol, such as the one presented in https://en.bitcoin.it/wiki/Contracts#Example_7:_Rapidly-adjusted_.28micro.29payments_to_a_pre-determined_party

JSON-RPC methods shown here may be sent via HTTPS or stratum protocol. It is easily adaptable to protocol buffers or another favored marshalling method.

Open channel

Client requests a public key. Server responds with a public key (K2). K2, converted to a bitcoin address, forms the unique identifier for this payment channel. Each public key returned must be unique.

{
  "method": "channel.open",
  "id": ...,
  "params": null
}
{
  "id": ...,
  "result": {
    "pubkey": "...hex-encoded ECDSA DER public key K2...",
    "timelock.min": 1394568158,   // minimum permitted refund tx timelock
    "timelock.max": 1394568158,   // maximum permitted refund tx timelock
    "timelock.prefer": 139456815, // recommended timelock value
    ...other server limits, such as payment channel maximum or minimum value...
  }
}

Provide refund transaction

Client creates signed T1 and unsigned T2, using public key K2. Client then provides the server T2, using the setRefund method. This implicitly tells the server the amount of value to be secured by the payment channel. This also explicitly provides the client public key, enabling two-way signed communications.

{
  "method": "channel.setRefund",
  "id": ...,
  "params": {
    "channel.id": "...base58-encoded channel id...",
    "pubkey": "...hex encoded ECDSA DER public key K1...",
    "tx": "...hex encoded T2...",
    "txInIdx": 0    // index of tx input to sign with K2
   }
}
{
  "id": ...,
  "result": {
    "signature": "...hex encoded server's signature of T2..."
  }
}

At this point, the server has approved of the proposed refund transaction T2, and the client may sign and broadcast it anytime after the time lock expires.

Commit channel funds, send first payment

Client now signs T1 and sends it to the server. The client may broadcast T1 to the network. The server should broadcast T1 to the network. At this point, when T1 is confirmed, the funds are locked in.

To handle up-front and avoid situations where a payment is under a network dust limit, the first payment (T3) is also provided.

{
  "method": "channel.commit",
  "id": ...,
  "params": {
    "channel.id": "...base58-encoded channel id...",
    "tx.commit": "...hex encoded T1...",
    "tx.firstPayment": "...hex encoded T3..."
   }
}
{
  "id": ...,
  "result": true
}

Make payments

Client creates a new version of transaction T3. The sequence number is incremented by 1, and N satoshis are removed from output K1, and added to output K2. Client re-signs the updated T3, and provides the signature and payment amount to the server. T3 must use the same time lock as in T2.

Make an unlimited number of payments. To close the payment channel, send a final version of T3 with sequence number 0xffffffff.

{
  "method": "channel.pay",
  "id": ...,
  "params": {
    "channel.id": "...base58-encoded channel id...",
    "signature": "...hex encoded signature for T3...",
    "amount": 50000
   }
}
{
  "id": ...,
  "result": true
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment