Apiwallet Documentation

Apiwallet is a Stroem enabled bitcoin wallet specifically designed to pay for API services. To control the Apiwallet it provides an HTTP API which is documented here.

Contents

See Also

Introduction

The Apiwallet is an open source bitcoin wallet that lets applications pay for API services. The wallet implements the Stroem open protocol designed for microtransactions. The Apiwallet is using the bitcoinj library and runs on the JVM platform. It supports wallet encryption and wallet generation from mnemonic codes. In addition to Stroem payments it supports basic bitcoin operations such as sending and receiving bitcoin.

To support stroem payments the wallet will set up bitcoin payment channels to a configured issuer. Currently the payment channel used is constructed from the CLTV contract as implemented in bitcoinj.

Operations

Method Path Parameters Description
GET ping
api/ping
Alive check, returns version
POST api/initialize new_password?, seed_code?, creation_time? Initialize the wallet
GET api/balance Wallet balance
GET api/receive_address Current receive address
POST api/fresh_receive_address Generate a new receive address
GET api/network_status Bitcoin network status
GET api/offer uri Retrieve an offer from a merchant
POST api/send to, amount, password? Send bitcoin with the bitcoin network
POST api/pay uri, limit, password? Pay stroem offer using uri
POST api/pay offer, limit, password? Pay retrieved stroem offer
POST api/open password? Prepare the wallet for stroem payments by setting up a channel if needed.
POST api/stroem enable Enable or disable payment channels to issuer and stroem payments

Parameters and Return Values

Parameters shall be url-encoded and for POST methods use Content-Type application/x-www-form-urlencoded. Optional parameters are marked by a ? in the table above.

Return values are JSON values that specified by protobuf specification and the protobuf version 3 json mapping.

In examples below using curl we assume the Apiwallet is accepting connections at http://apiwallet:9000.

Example

Pay a stroem offer specified by an uri if the requested amount is less than 3 mBTC:

curl http://apiwallet:9000/api/pay --data-urlencode "uri=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV"  --data-urlencode "limit=3 mBTC" --data-urlencode "password=correcthorsebattrystaple"

Typical response:

 {
 "result": {
   "code": "SUCCESS",
   "message": ""
  },
  "id": "3283089494891188575",
  "receipt": "PaymentReceipt(PaymentHash(2485674057329833655),2016-02-19T17:43:35.000Z,Signature(4242360482115804095942564028953717525474721300129512909492173114388416615958,108595024761595787914930369169740757507614251122494236004776875429712176808412))"
}

Wallet API

The Apiwallet is aimed at developers that are familiar with consuming APIs. The wallet itself provides an HTTP API for its operation. The return values are defined as protobuf messages, as defined in the api.proto file. All responses are returned in JSON format using protobuf 3 mappings.

In general, response status code is set to 200 OK for successful requests and otherwise the status code is set to an error code.

Ping

GET /api/ping

Keep alive and version check.

Reply type: Api.Ping

{
  "name": "apiwallet",
  "version": "0.5.0",
  "stroemVersion": "StroemVersion(0,5)"
}

Initialize

You must initialize the wallet before you can start using it. The initialization step creates a wallet, either from a seed_code or from random data. The response includes a bitcoin address that can be used to fund the wallet. You can optionally assign a password to encrypt the wallet file. It is highly recommened that you set a password. A passphrase for the seed is not supported.

When the wallet is initialized from a seed_code it will download the block chain from connected peers, searching for transactions from the point in time given by a creation_time parameter. During the download phase the wallet will be inaccessible. The download progress is written to the log.

POST /api/initialize

Parameter Description
new_password Password used to encrypt the wallet
seed_code Seed words, see BIP-0039
creation_time The time the seed was first used, time is unix time, i.e. seconds since epoch. Use now to express the current time.

Note keep the seed_code secret since it gives full access to the bitcoins stored in the wallet

The wallet is only initialized once and the password cannot be changed.

Initialize examples

Initialize with seed_code and password.
 curl http://apiwallet:9000/api/initialize --data-urlencode "seed_code=goat sound raise hungry raw only bomb shallow nice credit fatal release" --data-urlencode "creation_time=1458817060" --data-urlencode "new_password=correcthorsebattrystaple"

Reply type: Api.InitializeResponse

 {
   "message": "complete",
   "address": {
     "network": "main",
     "address": "1HXiHNSyZ27wWX4d6MMhXpXS29KxFzo629"
   }
 }
Initialize an unencrypted wallet with a randomly generated seed.
 curl -X POST http://apiwallet:9000/api/initialize

Reply type: Api.InitializeResponse

 {
   "message": "complete",
   "address": {
     "network": "main",
     "address": "1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z"
   }
 }

Access wallet seed

It is possible to retrieve the seed from a wallet by configuring with apiwallet.http.seedAccess=true (defaults to false) to allow an HTTP request to retrieve it by:

 curl -X POST http://apiwallet:9000/api/get_seed --data-urlencode "password=<...>"

Or, if the console CLI is enabled, the command get seed prints the seed. The seed value lets anyone reconstruct any previous or future bitcoin keys for the wallet so it should be kept secret.

Funding and Balance

To transfer funds to the wallet bitcoin can be sent either the address returned at initialize or use the following method to get a fresh bitcoin address.

POST /api/fresh_receive_address

Generates and returns a fresh address that will be watched for transactions.

curl -X POST http://apiwallet:9000/api/fresh_receive_address

Reply type: Api.BitcoinAddress

 {
    "network": "main",
    "address": "1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z"
 }

GET /api/receive_address

Returns the current address that is used for receiving transactions.

curl http://apiwallet:9000/api/receive_address

Reply type: Api.BitcoinAddress

 {
   "network": "main",
   "address": "1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z"
 }

GET /api/balance

Returns the current balance in the wallet.

curl http://apiwallet:9000/api/balance

Reply type: Api.WalletBalance

 {
   "currency": "BTC",
   "available": "0.08913685",
   "waiting": "0.00000000",
   "availableInChannels": "0.00972000",
   "waitingInChannels": "0.00000000",
   "total": "0.09885685"
 }

Balance waitingand waitingInChannels represents transactions that are waiting to be confirmed by the bitcoin network. The Apiwallet will only use available funds for payments. To make Stroem payments, funds need to be availableInChannels and to send bitcoin or set up new channels, bitcoin balance needs to be available. By the default configuration funds are considered available when its transaction is 3 or more blocks old.

Open

The open operation will open a connection to the issuer and set up a payment channel unless one exists. This method may have to be called to prepare the wallet, ahead of time, for payments, if the wallet is just installed or the wallet has not been used for a long time and existing payment channels have timed out.

POST /api/open

Sets up a payment channel to the issuer unless one is existing with sufficient amount of funds. The wallet needs to have enough funds available.

Parameter Description
password Password is needed for encrypted wallets

Open a connection to the issuer.

curl -X POST http://apiwallet:9000/api/open

Reply type: Api.ReturnCode

 {
   "code": "SUCCESS",
   "message": "Requested openChannel!"
 }

Pay

The pay operation is used to pay a stroem offer. The offer can either be fetched from a merchant automatically by the Apiwallet, when using the uri parameter, or it can be supplied as a parameter. If the requested amount is above a given limit, the operation will be aborted. The pay operation will open a new connection to the issuer if none is available.

If an existing payment channel exist and is available it will be used, else a new channel will be set up but it will not be available immediately which means the payment will fail. The Apiwallet will try to keep channels with available funds during continuous use by setting up new channels as needed when payments are made and the balance in existing channels are exhausted.

POST /api/pay

Parameter Description
uri uri to offer resource.
offer a JSON formatted offer
limit String specifying max amount to pay, e.g. "0.005 BTC" or "5 mBTC"
password Password is needed for encrypted wallets
Paying an offer uri

Paying an offer retrieved using an uri, limiting the amount payed to 0.004 BTC:

curl http://apiwallet:9000/api/pay --data-urlencode "uri=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV" --data-urlencode "limit=4 mBTC"

Reply type: Api.PaymentResult

 {
   "result": {
     "code": "SUCCESS",
     "message": ""
   },
   "id": "2660587913763177294",
   "receipt": "PaymentReceipt(PaymentHash(5988807602620052466),2016-04-11T22:07:58.000+02:00,Signature(68145062297523373021648555593647984078643791999959174711784375651680494956692,25627461157791812804916092765234127352111261017492965524405252287266011221531))"
 }
Paying a local offer

It is possible to receive an offer in a number of ways. The offer content defined by an uri can be obtained using theoffer operation.

Paying an offer stored in a local file "offer.json", from an encrypted wallet and limiting the amount payed to 2 mBTC:

curl http://apiwallet:9000/api/pay --data-urlencode offer@offer.json --data-urlencode "password=correcthorsebatterystaple" --data-urlencode "limit=2 mBTC"

Reply type: Api.PaymentResult

 {
   "result": {
     "code": "SUCCESS",
     "message": ""
   },
   "id": "5934894304710551614",
   "receipt": "PaymentReceipt(PaymentHash(-4092338735111561106),2016-04-11T22:25:05.000+02:00,Signature(63717011276904604456588979105360459979924828932940740336841691103201446697771,98621386164885436400514883060539294300685003447685452329901873018009056402141))"
 }

GET /api/offer

Parameter Description
uri uri to offer resource.
Retrieving an offer

Retrieve an offer in json format by fetching the content from a given uri:

curl -G http://apiwallet:9000/api/offer --data-urlencode "uri=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV"

Reply type: Api.Offer

 {
  "issuer": {
   "name": "strawpay.com",
   "publicKey":= "AvwcjN63B8VtqiCATPk47WNYNQLIReGxcKp24wnJVfk"
  },
  "merchant": {
  "name": "payment.strawpay.com",
  "publicKey": "AxAxA9rxpIaoijb5SC+J1HOODIvOKKK8awXLgU98hlEy"
  },
  "paymentUrl": "https://payment.strawpay.com/api/payment/PsRkTeWKtlL3",
  "currency": "BTC",
  "amount": "8404",
  "displayText": "Lorem ipsum dolor sit amet,",
  "verifiers": [{
  "name": "payment.strawpay.com",
  "publicKey": "AxAxA9rxpIaoijb5SC+J1HOODIvOKKK8awXLgU98hlEy"
  }],
  "validFor": "2700",
  "expires": "1475235783"
}
Offer request

When the uri is used by the Apiwallet to request an offer the issuer to be used for the payment is also added to the request. This lets the merchant decide if to accept the issuer. The returned offer details may depend on the issuer selected.

The Apiwallet also accepts, as an uri value, an extension of the bitcoin protocol where it looks for an extra parameter r.stroem used to retrieve the offer. Thus all three cases below represents the same offer uri:

uri=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV

uri=bitcoin:1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z?amount=0.00173200&r.stroem=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV

uri=bitcoin:?r.stroem=https://payment.strawpay.com/api/paymentrequest/SpTFL8yGAZyV

Note the ? is required in for the first parameter in the bitcoin uri.

Sending Bitcoin

POST /api/send

Parameter Description
to bitcoin address string
amount amount to send, string with unit or use allto send all available funds.
password Password is needed for an encrypted wallet
Send 13.4 mBTC to bitcoin address 1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z
curl http://apiwallet:9000/api/send --data-urlencode "to=1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z" --data-urlencode "amount=0.0134 BTC" 

Reply type: Api.SendResult

 {
   "result": {
     "code": "SUCCESS",
     "message": "sent 0.0134 BTC to 1GHXS6fcyPGqwGAeRnteMxovDQaJjAkK5z"
   },
   "txHash": "8bcd255643b41d11b5086af40764eb7dbb35f35716150dde29d0fed34d7e489b"
 }

Network Status

GET /api/network_status

curl http://apiwallet:9000/api/network_status

Reply type: Api.BitcoinNetworkStatus

 {
   "network": "main",
   "peers": 12,
   "heightPeers": 437060,
   "heightStore": 437060
 }

Close and Withdraw Funds

The Apiwallet supports standard bitcoin features so the funds in the wallet can be withdrawn by sending funds from the wallet. However, to support Stroem payments some funds are probably locked in one or two payment channels set up to the issuer. To close any payment channels before the expiry time, disable Stroem payments.

Disable stroem payments and send funds to 18nSLUTbNG2VeaUJMf9yEi88PTFTWrwNNP
curl -X POST http://apiwallet:9000/api/stroem --data-urlencode "stroem=false" "password=correcthorsebatterystaple"

Wait for any channels to close and returned funds to become available. Now send all funds to desired address.

curl http://apiwallet:9000/api/send --data-urlencode "to=18nSLUTbNG2VeaUJMf9yEi88PTFTWrwNNP" --data-urlencode "all" 

Wallet CLI

Console command line interface

If you enable the console, you can enter commands interactively from the console. This is for development purposes and is currently in experimental stage. The operations offered are the same as via the HTTP interface with some additions that may be of development use. You can type ?, h, or help to see the available commands.

acquire <amount> <unit>         Acquire promissory note from the issuer. (for testing only - no way to redeem)
available                       Show a list of spendable amounts with ordered from low to high confidence
balance                         Retrieve the wallet balance
check address <address>         Validate address string format and checksum for bitcoin network
check password                  Validates if a password is correct for this wallet
close                           Closes an open connection to the issuer
config                          Prints active configuration
consistent                      Calls consistent check on the wallet
decrypt                         Decrypts an encrypted wallet
disable                         Disables stroem payments, will settle channels and close connections
disconnect peers                Disconnect all connected peers at once.
dump block <hash>               Get block from store and print it
dump blocks <depth>             Print block headers from older until last received
dump channels                   Print a list of recently closed or open channels
dump full transactions          Print all stored bitcoin transactions
dump stroem transactions        Print all stored stroem transactions
dump transactions               Print all stored bitcoin transactions
enable                          Enables stroem payments, will set up channel if funds are available
encrypt                         Encrypts an unencrypted wallet
fresh receive                   Creates and print a fresh receive address
get offer <uri>                 Retrieve an offer and print it
get seed                        Print wallet seed code
help, h, ?                      Print this help text
issuer connection status        Shows connected states to issuer
network status                  Print  bitcoin network status
open                            Open a connection to the issuer
pay <uri> <limit> <unit>        Pay offer at uri, if the amount is lower or equal to limit
ping                            Issues a ping command to the issuer when connected
quit, q, exit                   Quits the application
receive                         Print the current receive address
replace <address> <txid>        Double spend all confirmed inputs from txid to a given address
send <address> <amount> <unit>  Sends bitcoin to a given address, units should be specified with one of BTC, mBTC, uBTC
send <address> all              Sends all spendable bitcoin in the wallet to a given address
settle                          Asks the issuer to settle an open connected channel
status                          Displays current status information