Merge pull request #333 from nodar-chkuaselidze/docs/clean-up
Docs: Update
This commit is contained in:
commit
54b930baba
@ -38,7 +38,7 @@ See the [Beginner's Guide][guide] for more in-depth installation instructions.
|
|||||||
## Documentation
|
## Documentation
|
||||||
|
|
||||||
- API Docs: http://bcoin.io/docs/
|
- API Docs: http://bcoin.io/docs/
|
||||||
- REST Docs: [docs/REST-RPC-API](docs/REST-RPC-API.md)
|
- REST Docs: http://bcoin.io/api-docs/index.html
|
||||||
- Docs: [docs/](docs/README.md)
|
- Docs: [docs/](docs/README.md)
|
||||||
|
|
||||||
## Support
|
## Support
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
Welcome to the bcoin docs!
|
Welcome to the bcoin docs!
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
- [Tutorials][tutorials]
|
|
||||||
- [Getting Started][getting-started]
|
- [Getting Started][getting-started]
|
||||||
- [Configuration][configuration]
|
- [Configuration][configuration]
|
||||||
- [Design][design]
|
|
||||||
- [Wallet System][wallet-system]
|
- [Wallet System][wallet-system]
|
||||||
|
- [Design][design]
|
||||||
|
- [Guides][guides]
|
||||||
|
|
||||||
## Running
|
## Running
|
||||||
- [Bcoin CLI][cli]
|
- [Bcoin CLI][cli]
|
||||||
@ -26,23 +26,16 @@ Welcome to the bcoin docs!
|
|||||||
- [Create and Sign TX][example-tx-create-sign]
|
- [Create and Sign TX][example-tx-create-sign]
|
||||||
- [Get Transaction from Chain][example-tx-from-chain]
|
- [Get Transaction from Chain][example-tx-from-chain]
|
||||||
|
|
||||||
## Advanced
|
|
||||||
- [Working with transactions][work-transactions]
|
|
||||||
- [Scripting][scripting]
|
|
||||||
|
|
||||||
[tutorials]: http://bcoin.io/guide-tutorial-list.html
|
|
||||||
|
|
||||||
[getting-started]: Beginner's-Guide.md
|
[getting-started]: Beginner's-Guide.md
|
||||||
[configuration]: Configuration.md
|
[configuration]: Configuration.md
|
||||||
[design]: Design.md
|
[design]: Design.md
|
||||||
[wallet-system]: Wallet-System.md
|
[wallet-system]: Wallet-System.md
|
||||||
|
[guides]: http://bcoin.io/guides.html
|
||||||
|
|
||||||
[cli]: CLI.md
|
[cli]: CLI.md
|
||||||
[browser]: Running-in-the-browser.md
|
[browser]: Running-in-the-browser.md
|
||||||
[rest-rpc]: REST-RPC-API.md
|
[rest-rpc]: http://bcoin.io/api-docs/index.html#introduction
|
||||||
|
|
||||||
[work-transactions]: Working-with-transactions.md
|
|
||||||
[scripting]: Scripting.md
|
|
||||||
|
|
||||||
[example-p2p]: Examples/connect-to-the-p2p-network.js
|
[example-p2p]: Examples/connect-to-the-p2p-network.js
|
||||||
[example-blockchain]: Examples/create-a-blockchain-and-mempool.js
|
[example-blockchain]: Examples/create-a-blockchain-and-mempool.js
|
||||||
|
|||||||
@ -1,958 +0,0 @@
|
|||||||
The default bcoin HTTP server listens on the standard RPC port (8332 for main).
|
|
||||||
It exposes a REST json api, as well as a JSON-RPC api.
|
|
||||||
|
|
||||||
## Auth
|
|
||||||
|
|
||||||
Auth is accomplished via HTTP Basic Auth, using your node's API key (passed via
|
|
||||||
`--api-key`).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` bash
|
|
||||||
$ curl http://x:[api-key]@127.0.0.1:8332/
|
|
||||||
```
|
|
||||||
|
|
||||||
## Errors
|
|
||||||
|
|
||||||
Errors will be returned with an http status code other than 200, containing a
|
|
||||||
JSON object in the form:
|
|
||||||
|
|
||||||
`{"error": { message: "message" } }`
|
|
||||||
|
|
||||||
|
|
||||||
## Node API
|
|
||||||
|
|
||||||
### POST /
|
|
||||||
|
|
||||||
Route for JSON-RPC requests, most of which mimic the bitcoind RPC calls
|
|
||||||
completely.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"method":"getblockchaininfo","params":[]}`
|
|
||||||
- Response Body: `{"id":...,"result":...}`
|
|
||||||
|
|
||||||
### GET /
|
|
||||||
|
|
||||||
Get server info. No params.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"version": "1.0.0-alpha",
|
|
||||||
"network": "regtest",
|
|
||||||
"chain": {
|
|
||||||
"height": 177,
|
|
||||||
"tip": "18037e4e4906a6c9580356612a42bb4127888354825f4232d811ef7e89af376a",
|
|
||||||
"progress": 0.9935725241578355
|
|
||||||
},
|
|
||||||
"pool": {
|
|
||||||
"host": "96.82.67.198",
|
|
||||||
"port": 48444,
|
|
||||||
"agent": "/bcoin:1.0.0-alpha/",
|
|
||||||
"services": "1001",
|
|
||||||
"outbound": 1,
|
|
||||||
"inbound": 1
|
|
||||||
},
|
|
||||||
"mempool": {
|
|
||||||
"tx": 1,
|
|
||||||
"size": 2776
|
|
||||||
},
|
|
||||||
"time": {
|
|
||||||
"uptime": 6,
|
|
||||||
"system": 1486696228,
|
|
||||||
"adjusted": 1486696228,
|
|
||||||
"offset": 0
|
|
||||||
},
|
|
||||||
"memory": {
|
|
||||||
"rss": 63,
|
|
||||||
"jsHeap": 24,
|
|
||||||
"jsHeapTotal": 34,
|
|
||||||
"nativeHeap": 28
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /coin/address/:address
|
|
||||||
|
|
||||||
Get coins by address. Returns coins in bcoin coin json format.
|
|
||||||
|
|
||||||
*Note: Without `index-address` option, it won't return from chain(only mempool).*
|
|
||||||
|
|
||||||
### GET /coin/:hash/:index
|
|
||||||
|
|
||||||
Get coin by outpoint (hash and index). Returns coin in bcoin coin json format.
|
|
||||||
|
|
||||||
### POST /coin/address
|
|
||||||
|
|
||||||
Get coins by addresses. Returns coins in bcoin coin json format.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"addresses":[...]}`
|
|
||||||
- Response Body: `[...]`
|
|
||||||
|
|
||||||
### GET /tx/:hash
|
|
||||||
|
|
||||||
Get transaction by TXID from Chain or Mempool. Returns TX in bcoin transaction json format.
|
|
||||||
|
|
||||||
*Note: Without `index-tx` option, it won't return from chain.*
|
|
||||||
|
|
||||||
### GET /tx/address/:address
|
|
||||||
|
|
||||||
Get transactions by address. Returns TXs in bcoin transaction json format.
|
|
||||||
|
|
||||||
### POST /tx/address
|
|
||||||
|
|
||||||
Get transactions by addresses. Returns TXs in bcoin transaction json format.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"addresses":[...]}`
|
|
||||||
- Response Body: `[...]`
|
|
||||||
|
|
||||||
### GET /block/:block
|
|
||||||
|
|
||||||
Get block by hash or height.
|
|
||||||
|
|
||||||
### GET /mempool
|
|
||||||
|
|
||||||
Get mempool snapshot (array of json txs).
|
|
||||||
|
|
||||||
### POST /broadcast
|
|
||||||
|
|
||||||
Broadcast a transaction by adding it to the node's mempool. If mempool
|
|
||||||
verification fails, the node will still forcefully advertise and relay the
|
|
||||||
transaction for the next 60 seconds.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"tx":"tx-hex"}`
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### GET /fee
|
|
||||||
|
|
||||||
Estimate smart fee.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: GET /fee?blocks=1
|
|
||||||
- Response Body: `{"rate":"0.0005"}`
|
|
||||||
|
|
||||||
### POST /reset
|
|
||||||
|
|
||||||
Reset blockchain to hash or height. The chain sync will be replayed from this height. Note that this will also rollback any wallets to the specified block.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: POST /reset?height=100000
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Wallet API
|
|
||||||
|
|
||||||
### Wallet Auth
|
|
||||||
|
|
||||||
Individual wallets have their own api keys, referred to internally as "tokens"
|
|
||||||
(a 32 byte hash - calculated as `HASH256(m/44'->ec-private-key|tokenDepth)`).
|
|
||||||
|
|
||||||
A wallet is always created with a corresponding token. When using api endpoints
|
|
||||||
for a specific wallet, the token must be sent back in the query string or json
|
|
||||||
body.
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
```
|
|
||||||
POST /wallet/:id/send
|
|
||||||
{
|
|
||||||
token: "64 character hex string",
|
|
||||||
...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /wallet/:id/tx/:hash?token=[64 character hex string]
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/_admin/rescan
|
|
||||||
|
|
||||||
Initiates a blockchain rescan for the walletdb. Wallets will be rolled back to the specified height (transactions above this height will be unconfirmed).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: POST /wallet/_admin/rescan?height=100000
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### POST /wallet/_admin/resend
|
|
||||||
|
|
||||||
Rebroadcast all pending transactions in all wallets.
|
|
||||||
|
|
||||||
### POST /wallet/_admin/backup
|
|
||||||
|
|
||||||
Safely backup the wallet database to specified path (creates a clone of the database).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: POST /wallet/_admin/backup?path=/home/user/walletdb-backup.ldb
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### GET /wallet/_admin/wallets
|
|
||||||
|
|
||||||
List all wallet IDs. Returns an array of strings.
|
|
||||||
|
|
||||||
### GET /wallet/:id
|
|
||||||
|
|
||||||
Get wallet info by ID.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"network": "regtest",
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"initialized": true,
|
|
||||||
"watchOnly": false,
|
|
||||||
"accountDepth": 1,
|
|
||||||
"token": "2d04e217877f15ba920d02c24c6c18f4d39df92f3ae851bec37f0ade063244b2",
|
|
||||||
"tokenDepth": 0,
|
|
||||||
"state": {
|
|
||||||
"tx": 177,
|
|
||||||
"coin": 177,
|
|
||||||
"unconfirmed": "8150.0",
|
|
||||||
"confirmed": "8150.0"
|
|
||||||
},
|
|
||||||
"master": {
|
|
||||||
"encrypted": false
|
|
||||||
},
|
|
||||||
"account": {
|
|
||||||
"name": "default",
|
|
||||||
"initialized": true,
|
|
||||||
"witness": false,
|
|
||||||
"watchOnly": false,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"m": 1,
|
|
||||||
"n": 1,
|
|
||||||
"accountIndex": 0,
|
|
||||||
"receiveDepth": 8,
|
|
||||||
"changeDepth": 1,
|
|
||||||
"nestedDepth": 0,
|
|
||||||
"lookahead": 10,
|
|
||||||
"receiveAddress": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS",
|
|
||||||
"nestedAddress": null,
|
|
||||||
"changeAddress": "n3nFYgQR2mrLwC3X66xHNsx4UqhS3rkSnY",
|
|
||||||
"accountKey": "tpubDC5u44zLNUVo2gPVdqCbtX644PKccH5VZB3nqUgeCiwKoi6BQZGtr5d6hhougcD6PqjszsbR3xHrQ5k8yTbUt64aSthWuNdGi7zSwfGVuxc",
|
|
||||||
"keys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /wallet/:id/master
|
|
||||||
|
|
||||||
Get wallet master HD key. This is normally censored in the wallet info route. The provided api key must have _admin_ access.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"encrypted": false,
|
|
||||||
"key": {
|
|
||||||
"xprivkey": "tprv8ZgxMBicQKsPe7977psQCjBBjWtLDoJVPiiKog42RCoShJLJATYeSkNTzdwfgpkcqwrPYAmRCeudd6kkVWrs2kH5fnTaxrHhi1TfvgxJsZD",
|
|
||||||
"mnemonic": {
|
|
||||||
"bits": 128,
|
|
||||||
"language": "english",
|
|
||||||
"entropy": "a560ac7eb5c2ed412a4ba0790f73449d",
|
|
||||||
"phrase": "pistol air cabbage high conduct party powder inject jungle knee spell derive",
|
|
||||||
"passphrase": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### PUT /wallet/:id
|
|
||||||
|
|
||||||
Create a new wallet with a specified ID.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: PUT /wallet/foo
|
|
||||||
- Request Body: `{"type":"pubkeyhash"}`
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"network": "regtest",
|
|
||||||
"wid": 2,
|
|
||||||
"id": "foo",
|
|
||||||
"initialized": true,
|
|
||||||
"watchOnly": false,
|
|
||||||
"accountDepth": 1,
|
|
||||||
"token": "d9de1ddc83bf058d14520a203df6ade0dc92a684aebfac57b667705b4cac3916",
|
|
||||||
"tokenDepth": 0,
|
|
||||||
"state": {
|
|
||||||
"tx": 0,
|
|
||||||
"coin": 0,
|
|
||||||
"unconfirmed": "0.0",
|
|
||||||
"confirmed": "0.0"
|
|
||||||
},
|
|
||||||
"master": {
|
|
||||||
"encrypted": false
|
|
||||||
},
|
|
||||||
"account": {
|
|
||||||
"name": "default",
|
|
||||||
"initialized": true,
|
|
||||||
"witness": false,
|
|
||||||
"watchOnly": false,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"m": 1,
|
|
||||||
"n": 1,
|
|
||||||
"accountIndex": 0,
|
|
||||||
"receiveDepth": 1,
|
|
||||||
"changeDepth": 1,
|
|
||||||
"nestedDepth": 0,
|
|
||||||
"lookahead": 10,
|
|
||||||
"receiveAddress": "muYkrSDbD8UhyWBMXxXf99EKWn22YqmwyF",
|
|
||||||
"nestedAddress": null,
|
|
||||||
"changeAddress": "mwveV7A6svE5EGGSduZmMKTwcbE775NVFt",
|
|
||||||
"accountKey": "tpubDDh2XgSds1vBbeVgye88gsGQeCityoywRndtyrXcmvWqCgsFUyUKwzeDv8HiJhu9fC8jRAFMqxr4jj8eRTNTycmMao5wmsAScVf4jSMdPYZ",
|
|
||||||
"keys": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /wallet/:id/account
|
|
||||||
|
|
||||||
List all account names (array indicies map directly to bip44 account indicies).
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
[
|
|
||||||
"default"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /wallet/:id/account/:account
|
|
||||||
|
|
||||||
Get account info.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"name": "default",
|
|
||||||
"initialized": true,
|
|
||||||
"witness": false,
|
|
||||||
"watchOnly": false,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"m": 1,
|
|
||||||
"n": 1,
|
|
||||||
"accountIndex": 0,
|
|
||||||
"receiveDepth": 8,
|
|
||||||
"changeDepth": 1,
|
|
||||||
"nestedDepth": 0,
|
|
||||||
"lookahead": 10,
|
|
||||||
"receiveAddress": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS",
|
|
||||||
"nestedAddress": null,
|
|
||||||
"changeAddress": "n3nFYgQR2mrLwC3X66xHNsx4UqhS3rkSnY",
|
|
||||||
"accountKey": "tpubDC5u44zLNUVo2gPVdqCbtX644PKccH5VZB3nqUgeCiwKoi6BQZGtr5d6hhougcD6PqjszsbR3xHrQ5k8yTbUt64aSthWuNdGi7zSwfGVuxc",
|
|
||||||
"keys": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### PUT /wallet/:id/account/:name
|
|
||||||
|
|
||||||
Create account with specified account name.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: PUT /wallet/foo/account/my-account
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"name": "menace",
|
|
||||||
"initialized": true,
|
|
||||||
"witness": false,
|
|
||||||
"watchOnly": false,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"m": 1,
|
|
||||||
"n": 1,
|
|
||||||
"accountIndex": 1,
|
|
||||||
"receiveDepth": 1,
|
|
||||||
"changeDepth": 1,
|
|
||||||
"nestedDepth": 0,
|
|
||||||
"lookahead": 10,
|
|
||||||
"receiveAddress": "mg7b3H3ZCHx3fwvUf8gaRHwcgsL7WdJQXv",
|
|
||||||
"nestedAddress": null,
|
|
||||||
"changeAddress": "mkYtQFpxDcqutMJtyzKNFPnn97zhft56wH",
|
|
||||||
"accountKey": "tpubDC5u44zLNUVo55dtQsJRsbQgeNfrp8ctxVEdDqDQtR7ES9XG5h1SGhkv2HCuKA2RZysaFzkuy5bgxF9egvG5BJgapWwbYMU4BJ1SeSj916G",
|
|
||||||
"keys": []
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/:id/passphrase
|
|
||||||
|
|
||||||
Change wallet passphrase. Encrypt if unencrypted.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"old":"hunter2","passphrase":"hunter3"}`
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### POST /wallet/:id/unlock
|
|
||||||
|
|
||||||
Derive the AES key from passphrase and hold it in memory for a specified number
|
|
||||||
of seconds. __Note:__ During this time, account creation and signing of
|
|
||||||
transactions will _not_ require a passphrase.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"timeout":60,"passphrase":"hunter3"}`
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### POST /wallet/:id/lock
|
|
||||||
|
|
||||||
If `unlock` was called, zero the derived AES key and revert to normal behavior.
|
|
||||||
|
|
||||||
### POST /wallet/:id/import
|
|
||||||
|
|
||||||
Import a standard WIF key. Note that imported keys do not exist anywhere in the
|
|
||||||
wallet's HD tree. They can be associated with accounts but will _not_ be
|
|
||||||
properly backed up with only the mnemonic.
|
|
||||||
|
|
||||||
A rescan will be required to see any transaction history associated with the
|
|
||||||
key.
|
|
||||||
|
|
||||||
### POST /wallet/:id/retoken
|
|
||||||
|
|
||||||
Derive a new wallet token, required for access of this particular wallet.
|
|
||||||
|
|
||||||
__Note__: if you happen to lose the returned token, you _will not_ be able to
|
|
||||||
access the wallet.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"token": "2d04e217877f15ba920d02c24c6c18f4d39df92f3ae851bec37f0ade063244b2"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/:id/send
|
|
||||||
|
|
||||||
Create, sign, and send a transaction.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"rate": "0.00020",
|
|
||||||
"outputs": [{
|
|
||||||
"value": "5.0",
|
|
||||||
"address": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"hash": "0de09025e68b78e13f5543f46a9516fa37fcc06409bf03eda0e85ed34018f822",
|
|
||||||
"height": -1,
|
|
||||||
"block": null,
|
|
||||||
"time": 0,
|
|
||||||
"mtime": 1486685530,
|
|
||||||
"date": "2017-02-10T00:12:10Z",
|
|
||||||
"index": -1,
|
|
||||||
"size": 226,
|
|
||||||
"virtualSize": 226,
|
|
||||||
"fee": "0.0000454",
|
|
||||||
"rate": "0.00020088",
|
|
||||||
"confirmations": 0,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"value": "50.0",
|
|
||||||
"address": "n4UANJbj2ZWy1kgt9g45XFGp57FQvqR8ZJ",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": false,
|
|
||||||
"derivation": "m/0'/0/0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"value": "5.0",
|
|
||||||
"address": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": false,
|
|
||||||
"derivation": "m/0'/0/7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "44.9999546",
|
|
||||||
"address": "n3nFYgQR2mrLwC3X66xHNsx4UqhS3rkSnY",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": true,
|
|
||||||
"derivation": "m/0'/1/0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tx": "0100000001c5b23b4348b7fa801f498465e06f9e80cf2f61eead23028de14b67fa78df3716000000006b483045022100d3d4d945cdd85f0ed561ae8da549cb083ab37d82fcff5b9023f0cce608f1dffe02206fc1fd866575061dcfa3d12f691c0a2f03041bdb75a36cd72098be096ff62a810121021b018b19426faa59fdda7f57e68c42d925752454d9ea0d6feed8ac186074a4bcffffffff020065cd1d000000001976a91494bc546a84c481fbd30d34cfeeb58fd20d8a59bc88ac447b380c010000001976a914f4376876aa04f36fc71a2618878986504e40ef9c88ac00000000"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/:id/create
|
|
||||||
|
|
||||||
Create and template a transaction (useful for multisig).
|
|
||||||
Do not broadcast or add to wallet.
|
|
||||||
|
|
||||||
- Request Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"outputs": [{
|
|
||||||
"value": "5.0",
|
|
||||||
"address": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"hash": "0799a1d3ebfd108d2578a60e1b685350d42e1ef4d5cd326f99b8bf794c81ed17",
|
|
||||||
"witnessHash": "0799a1d3ebfd108d2578a60e1b685350d42e1ef4d5cd326f99b8bf794c81ed17",
|
|
||||||
"fee": "0.0000454",
|
|
||||||
"rate": "0.00020088",
|
|
||||||
"mtime": 1486686322,
|
|
||||||
"version": 1,
|
|
||||||
"flag": 1,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"prevout": {
|
|
||||||
"hash": "6dd8dfa9b425a4126061a1032bc6ff6e208b75ee09d0aac089d105dcf972465a",
|
|
||||||
"index": 0
|
|
||||||
},
|
|
||||||
"script": "483045022100e7f1d57e47cd8a28b7c27e015b291f3fd43a6eb0c051a4b65d8697b5133c29f5022020cada0f62a32aecd473f606780b2aef3fd9cbd44cfd5e9e3d9fe6eee32912df012102272dae7ff2302597cb785fd95529da6c07e32946e65ead419291258aa7b17871",
|
|
||||||
"witness": "00",
|
|
||||||
"sequence": 4294967295,
|
|
||||||
"coin": {
|
|
||||||
"version": 1,
|
|
||||||
"height": 2,
|
|
||||||
"value": "50.0",
|
|
||||||
"script": "76a9149621fb4fc6e2e48538f56928f79bef968bf17ac888ac",
|
|
||||||
"address": "muCnMvAoUFZXzuao4oy3vQJFcUntax53wE",
|
|
||||||
"coinbase": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"value": "5.0",
|
|
||||||
"script": "76a91494bc546a84c481fbd30d34cfeeb58fd20d8a59bc88ac",
|
|
||||||
"address": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "44.9999546",
|
|
||||||
"script": "76a91458e0ea4c9722e7d079ebadb75cb3d8c16dafae7188ac",
|
|
||||||
"address": "mocuCKUU6oS6n1yyx81Au71An252SUYwDW"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"locktime": 0
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/:id/sign
|
|
||||||
|
|
||||||
Sign a templated transaction (useful for multisig).
|
|
||||||
|
|
||||||
### POST /wallet/:id/zap
|
|
||||||
|
|
||||||
Remove all pending transactions older than a specified age. Returns array of txids.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: POST /wallet/primary/zap?age=3600
|
|
||||||
- Response Body: `[...]`
|
|
||||||
|
|
||||||
### DEL /wallet/:id/tx/:hash
|
|
||||||
|
|
||||||
Remove a pending transaction.
|
|
||||||
|
|
||||||
### GET /wallet/:id/block
|
|
||||||
|
|
||||||
List all block heights which contain any wallet txs.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body: `[1,2,3]`
|
|
||||||
|
|
||||||
### GET /wallet/:id/block/:height
|
|
||||||
|
|
||||||
Get block info by height. Contains a list of all wallet txs included in the
|
|
||||||
block.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: GET /wallet/primary/block/3
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"hash": "39864ce2f29635638bbdc3e943b3a182040fdceb6679fa3dabc8c827e05ff6a7",
|
|
||||||
"height": 3,
|
|
||||||
"time": 1485471341,
|
|
||||||
"hashes": [
|
|
||||||
"dd1a110edcdcbb3110a1cbe0a545e4b0a7813ffa5e77df691478205191dad66f"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### PUT /wallet/:id/shared-key
|
|
||||||
|
|
||||||
Add a shared xpubkey to wallet. Must be a `multisig` wallet.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request Body: `{"accountKey":"tpubDC5u44zLNUVo55dtQsJRsbQgeNfrp8ctxVEdDqDQtR7ES9XG5h1SGhkv2HCuKA2RZysaFzkuy5bgxF9egvG5BJgapWwbYMU4BJ1SeSj916G"}`
|
|
||||||
- Response Body: `{"success":true}`
|
|
||||||
|
|
||||||
### DEL /wallet/:id/shared-key
|
|
||||||
|
|
||||||
Remove shared xpubkey from wallet if present.
|
|
||||||
|
|
||||||
### GET /wallet/:id/key/:address
|
|
||||||
|
|
||||||
Get wallet key by address.
|
|
||||||
|
|
||||||
### GET /wallet/:id/wif/:address
|
|
||||||
|
|
||||||
Get wallet private key (WIF format) by address.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: GET /wallet/primary/wif/mwX8J1CDGUqeQcJPnjNBG4s97vhQsJG7Eq
|
|
||||||
- Response Body: `"cQpRMiBcqiyjFratU2ugGEWCmGM8ctb15vhFWd74j3t4m8EzriG2"`
|
|
||||||
|
|
||||||
### POST /wallet/:id/address
|
|
||||||
|
|
||||||
Derive new receiving address for account.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"network": "regtest",
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"branch": 0,
|
|
||||||
"index": 9,
|
|
||||||
"witness": false,
|
|
||||||
"nested": false,
|
|
||||||
"publicKey": "02801d9457837ed50e9538ee1806b6598e12a3c259fdc9258bbd32934f22cb1f80",
|
|
||||||
"script": null,
|
|
||||||
"program": null,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"address": "mwX8J1CDGUqeQcJPnjNBG4s97vhQsJG7Eq"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### POST /wallet/:id/change
|
|
||||||
|
|
||||||
Derive new change address for account.
|
|
||||||
|
|
||||||
### POST /wallet/:id/nested
|
|
||||||
|
|
||||||
Derive new nested p2sh receiving address for account.
|
|
||||||
|
|
||||||
### GET /wallet/:id/balance
|
|
||||||
|
|
||||||
Get wallet or account balance.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"account": -1,
|
|
||||||
"unconfirmed": "8149.9999546",
|
|
||||||
"confirmed": "8150.0"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /wallet/:id/coin
|
|
||||||
|
|
||||||
List all wallet coins available.
|
|
||||||
|
|
||||||
### GET /wallet/:id/locked
|
|
||||||
|
|
||||||
Get all locked outpoints.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
[{"hash":"dd1a110edcdcbb3110a1cbe0a545e4b0a7813ffa5e77df691478205191dad66f","index":0}]
|
|
||||||
```
|
|
||||||
|
|
||||||
### PUT /wallet/:id/locked/:hash/:index
|
|
||||||
|
|
||||||
Lock outpoints.
|
|
||||||
|
|
||||||
### DEL /wallet/:id/locked/:hash/:index
|
|
||||||
|
|
||||||
Unlock outpoints.
|
|
||||||
|
|
||||||
### GET /wallet/:id/coin/:hash/:index
|
|
||||||
|
|
||||||
Get wallet coins.
|
|
||||||
|
|
||||||
Example
|
|
||||||
|
|
||||||
- Response Body:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"version": 1,
|
|
||||||
"height": -1,
|
|
||||||
"value": "44.9999546",
|
|
||||||
"script": "76a914f4376876aa04f36fc71a2618878986504e40ef9c88ac",
|
|
||||||
"address": "n3nFYgQR2mrLwC3X66xHNsx4UqhS3rkSnY",
|
|
||||||
"coinbase": false,
|
|
||||||
"hash": "0de09025e68b78e13f5543f46a9516fa37fcc06409bf03eda0e85ed34018f822",
|
|
||||||
"index": 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### GET /wallet/:id/tx/history
|
|
||||||
|
|
||||||
Get wallet TX history. Returns array of tx details.
|
|
||||||
|
|
||||||
### GET /wallet/:id/tx/unconfirmed
|
|
||||||
|
|
||||||
Get pending wallet transactions. Returns array of tx details.
|
|
||||||
|
|
||||||
### GET /wallet/:id/tx/range
|
|
||||||
|
|
||||||
Get range of wallet transactions by timestamp. Returns array of tx details.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
- Request: GET /wallet/primary/tx/range?start=1486695017&end=1486695359
|
|
||||||
- Response Body: `[{tx-details}]`
|
|
||||||
|
|
||||||
### GET /wallet/:id/tx/last
|
|
||||||
|
|
||||||
Get last N wallet transactions.
|
|
||||||
|
|
||||||
### GET /wallet/:id/tx/:hash
|
|
||||||
|
|
||||||
Get wallet transaction details.
|
|
||||||
|
|
||||||
### POST /wallet/:id/resend
|
|
||||||
|
|
||||||
Rebroadcast all pending wallet transactions.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Wallet Events
|
|
||||||
|
|
||||||
Wallet events use the socket.io protocol.
|
|
||||||
|
|
||||||
Socket IO implementations:
|
|
||||||
|
|
||||||
- JS: https://github.com/socketio/socket.io-client
|
|
||||||
- Python: https://github.com/miguelgrinberg/python-socketio
|
|
||||||
- Go: https://github.com/googollee/go-socket.io
|
|
||||||
- C++: https://github.com/socketio/socket.io-client-cpp
|
|
||||||
|
|
||||||
### Wallet Socket Auth
|
|
||||||
|
|
||||||
Authentication with the API server must be completed before any other events
|
|
||||||
will be accepted.
|
|
||||||
|
|
||||||
Note that even if the server API key is disabled on the test server, the
|
|
||||||
`auth` event must still be sent to complete the handshake.
|
|
||||||
|
|
||||||
`emit('auth', 'server-api-key')`
|
|
||||||
|
|
||||||
The server will respond with a socket.io ACK packet once auth is completed.
|
|
||||||
|
|
||||||
### Listening on a wallet
|
|
||||||
|
|
||||||
After creating a websocket and authing with the server, you must send a `wallet
|
|
||||||
join` event to listen for events on a wallet.
|
|
||||||
|
|
||||||
`emit('wallet join', 'wallet-id', 'wallet-token')`
|
|
||||||
|
|
||||||
### Unlistening on a wallet
|
|
||||||
|
|
||||||
`emit('wallet leave', 'wallet-id')`
|
|
||||||
|
|
||||||
### Wallet Events
|
|
||||||
|
|
||||||
#### `version`
|
|
||||||
|
|
||||||
Emitted on connection.
|
|
||||||
|
|
||||||
Returns version. Object in the form:
|
|
||||||
`[{ version: 'v1.0.0-alpha', agent: '/bcoin:v1.0.0-alpha/', network: 'main' }]`.
|
|
||||||
|
|
||||||
#### `wallet tx`
|
|
||||||
|
|
||||||
Received on transaction.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"hash": "0de09025e68b78e13f5543f46a9516fa37fcc06409bf03eda0e85ed34018f822",
|
|
||||||
"height": -1,
|
|
||||||
"block": null,
|
|
||||||
"time": 0,
|
|
||||||
"mtime": 1486685530,
|
|
||||||
"date": "2017-02-10T00:12:10Z",
|
|
||||||
"index": -1,
|
|
||||||
"size": 226,
|
|
||||||
"virtualSize": 226,
|
|
||||||
"fee": "0.0000454",
|
|
||||||
"rate": "0.00020088",
|
|
||||||
"confirmations": 0,
|
|
||||||
"inputs": [
|
|
||||||
{
|
|
||||||
"value": "50.0",
|
|
||||||
"address": "n4UANJbj2ZWy1kgt9g45XFGp57FQvqR8ZJ",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": false,
|
|
||||||
"derivation": "m/0'/0/0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"value": "5.0",
|
|
||||||
"address": "mu5Puppq4Es3mibRskMwoGjoZujHCFRwGS",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": false,
|
|
||||||
"derivation": "m/0'/0/7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "44.9999546",
|
|
||||||
"address": "n3nFYgQR2mrLwC3X66xHNsx4UqhS3rkSnY",
|
|
||||||
"path": {
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"change": true,
|
|
||||||
"derivation": "m/0'/1/0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"tx": "0100000001c5b23b4348b7fa801f498465e06f9e80cf2f61eead23028de14b67fa78df3716000000006b483045022100d3d4d945cdd85f0ed561ae8da549cb083ab37d82fcff5b9023f0cce608f1dffe02206fc1fd866575061dcfa3d12f691c0a2f03041bdb75a36cd72098be096ff62a810121021b018b19426faa59fdda7f57e68c42d925752454d9ea0d6feed8ac186074a4bcffffffff020065cd1d000000001976a91494bc546a84c481fbd30d34cfeeb58fd20d8a59bc88ac447b380c010000001976a914f4376876aa04f36fc71a2618878986504e40ef9c88ac00000000"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `wallet conflict`
|
|
||||||
|
|
||||||
Received on double spend.
|
|
||||||
|
|
||||||
Returns tx details of removed double spender.
|
|
||||||
|
|
||||||
#### `wallet confirmed`
|
|
||||||
|
|
||||||
Received when a transaction is confirmed.
|
|
||||||
|
|
||||||
Returns tx details.
|
|
||||||
|
|
||||||
#### `wallet unconfirmed`
|
|
||||||
|
|
||||||
Received if a transaction was changed from
|
|
||||||
confirmed->unconfirmed as the result of a reorg.
|
|
||||||
|
|
||||||
Returns tx details.
|
|
||||||
|
|
||||||
#### `wallet balance`
|
|
||||||
|
|
||||||
Received on balance update. Only emitted for
|
|
||||||
entire wallet balance (not individual accounts).
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"unconfirmed": "8149.9999546",
|
|
||||||
"confirmed": "8150.0"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `wallet address`
|
|
||||||
|
|
||||||
Received when a new address is derived.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
|
|
||||||
``` json
|
|
||||||
{
|
|
||||||
"network": "regtest",
|
|
||||||
"wid": 1,
|
|
||||||
"id": "primary",
|
|
||||||
"name": "default",
|
|
||||||
"account": 0,
|
|
||||||
"branch": 0,
|
|
||||||
"index": 9,
|
|
||||||
"witness": false,
|
|
||||||
"nested": false,
|
|
||||||
"publicKey": "02801d9457837ed50e9538ee1806b6598e12a3c259fdc9258bbd32934f22cb1f80",
|
|
||||||
"script": null,
|
|
||||||
"program": null,
|
|
||||||
"type": "pubkeyhash",
|
|
||||||
"address": "mwX8J1CDGUqeQcJPnjNBG4s97vhQsJG7Eq"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
@ -1,50 +0,0 @@
|
|||||||
Scripts are array-like objects with some helper functions.
|
|
||||||
|
|
||||||
``` js
|
|
||||||
const bcoin = require('bcoin');
|
|
||||||
const assert = require('assert');
|
|
||||||
const Script = bcoin.script;
|
|
||||||
const Witness = bcoin.witness;
|
|
||||||
const Stack = bcoin.stack;
|
|
||||||
|
|
||||||
const output = new Script();
|
|
||||||
output.pushSym('OP_DROP');
|
|
||||||
output.pushSym('OP_ADD');
|
|
||||||
output.pushInt(7);
|
|
||||||
output.pushSym('OP_NUMEQUAL');
|
|
||||||
// Compile the script to its binary representation
|
|
||||||
// (you must do this if you change something!).
|
|
||||||
assert(output.getSmall(2) === 7); // compiled as OP_7
|
|
||||||
output.compile();
|
|
||||||
|
|
||||||
const input = new Script();
|
|
||||||
input.setString(0, 'hello world'); // add some metadata
|
|
||||||
input.pushInt(2);
|
|
||||||
input.pushInt(5);
|
|
||||||
input.push(input.shift());
|
|
||||||
assert(input.getString(2) === 'hello world');
|
|
||||||
input.compile();
|
|
||||||
|
|
||||||
// A stack is another array-like object which contains
|
|
||||||
// only Buffers (whereas scripts contain Opcode objects).
|
|
||||||
const stack = new Stack();
|
|
||||||
input.execute(stack);
|
|
||||||
output.execute(stack);
|
|
||||||
// Verify the script was successful in its execution:
|
|
||||||
assert(stack.length === 1);
|
|
||||||
assert(stack.getBool(-1) === true);
|
|
||||||
```
|
|
||||||
|
|
||||||
Using a witness would be similar, but witnesses do not get executed, they
|
|
||||||
simply _become_ the stack. The witness object itself is very similar to the
|
|
||||||
Stack object (an array-like object containing Buffers).
|
|
||||||
|
|
||||||
``` js
|
|
||||||
const witness = new Witness();
|
|
||||||
witness.pushInt(2);
|
|
||||||
witness.pushInt(5);
|
|
||||||
witness.pushString('hello world');
|
|
||||||
|
|
||||||
const stack = witness.toStack();
|
|
||||||
output.execute(stack);
|
|
||||||
```
|
|
||||||
@ -1,153 +0,0 @@
|
|||||||
## TX creation
|
|
||||||
|
|
||||||
Normal transactions in bcoin are immutable. The primary TX object contains a
|
|
||||||
bunch of consensus and policy checking methods. A lot of it is for internal use
|
|
||||||
and pretty boring for users of this library.
|
|
||||||
|
|
||||||
Bcoin also offers a mutable transaction object (MTX). Mutable transactions
|
|
||||||
inherit from the TX object, but can also be signed and modified.
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var bcoin = require('bcoin');
|
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
// Create an HD master keypair.
|
|
||||||
var master = bcoin.hd.generate();
|
|
||||||
|
|
||||||
// Derive another private hd key (we don't want to use our master key!).
|
|
||||||
var key = master.derive('m/44/0/0/0/0');
|
|
||||||
|
|
||||||
// Create a "keyring" object. A keyring object is basically a key manager that
|
|
||||||
// is also able to tell you info such as: your redeem script, your scripthash,
|
|
||||||
// your program hash, your pubkey hash, your scripthash program hash, etc.
|
|
||||||
// In this case, we'll make it simple and just add one key for a
|
|
||||||
// pubkeyhash address. `getPublicKey` returns the non-hd public key.
|
|
||||||
var keyring = new bcoin.keyring(key.privateKey);
|
|
||||||
|
|
||||||
console.log(keyring.getAddress());
|
|
||||||
|
|
||||||
// Create a fake coinbase for our funding.
|
|
||||||
var cb = new bcoin.mtx();
|
|
||||||
|
|
||||||
// Add a typical coinbase input
|
|
||||||
cb.addInput({
|
|
||||||
prevout: new bcoin.outpoint(),
|
|
||||||
script: new bcoin.script(),
|
|
||||||
sequence: 0xffffffff
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send 50,000 satoshis to ourself.
|
|
||||||
cb.addOutput({
|
|
||||||
address: keyring.getAddress(),
|
|
||||||
value: 50000
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create our redeeming transaction.
|
|
||||||
var mtx = new bcoin.mtx();
|
|
||||||
|
|
||||||
// Add output 0 from our coinbase as an input.
|
|
||||||
mtx.addTX(cb, 0);
|
|
||||||
|
|
||||||
// Send 10,000 satoshis to ourself,
|
|
||||||
// creating a fee of 40,000 satoshis.
|
|
||||||
mtx.addOutput({
|
|
||||||
address: keyring.getAddress(),
|
|
||||||
value: 10000
|
|
||||||
});
|
|
||||||
|
|
||||||
// Sign input 0: pass in our keyring.
|
|
||||||
mtx.sign(keyring);
|
|
||||||
|
|
||||||
// The transaction should now verify.
|
|
||||||
assert(mtx.verify());
|
|
||||||
assert(mtx.getFee() === 40000);
|
|
||||||
|
|
||||||
// Commit our transaction and make it immutable.
|
|
||||||
// This turns it from an MTX into a TX object.
|
|
||||||
var tx = mtx.toTX();
|
|
||||||
|
|
||||||
// The transaction should still verify.
|
|
||||||
// Regular transactions require a coin
|
|
||||||
// viewpoint to be passed in.
|
|
||||||
assert(tx.verify(mtx.view));
|
|
||||||
assert(tx.getFee(mtx.view) === 40000);
|
|
||||||
```
|
|
||||||
|
|
||||||
### Coin Selection
|
|
||||||
|
|
||||||
The above method works, but is pretty contrived. In reality, you probably
|
|
||||||
wouldn't select inputs and calculate the fee by hand. You would want a
|
|
||||||
change output added. Bcoin has a nice method of dealing with this.
|
|
||||||
|
|
||||||
Let's try it more realistically:
|
|
||||||
|
|
||||||
``` js
|
|
||||||
var bcoin = require('bcoin');
|
|
||||||
var assert = require('assert');
|
|
||||||
|
|
||||||
var master = bcoin.hd.generate();
|
|
||||||
var key = master.derive('m/44/0/0/0/0');
|
|
||||||
var keyring = new bcoin.keyring(key.privateKey);
|
|
||||||
var cb = new bcoin.mtx();
|
|
||||||
|
|
||||||
cb.addInput({
|
|
||||||
prevout: new bcoin.outpoint(),
|
|
||||||
script: new bcoin.script(),
|
|
||||||
sequence: 0xffffffff
|
|
||||||
});
|
|
||||||
|
|
||||||
// Send 50,000 satoshis to ourselves.
|
|
||||||
cb.addOutput({
|
|
||||||
address: keyring.getAddress(),
|
|
||||||
value: 50000
|
|
||||||
});
|
|
||||||
|
|
||||||
// Our available coins.
|
|
||||||
var coins = [];
|
|
||||||
|
|
||||||
// Convert the coinbase output to a Coin
|
|
||||||
// object and add it to our available coins.
|
|
||||||
// In reality you might get these coins from a wallet.
|
|
||||||
var coin = bcoin.coin.fromTX(cb, 0, -1);
|
|
||||||
coins.push(coin);
|
|
||||||
|
|
||||||
// Create our redeeming transaction.
|
|
||||||
var mtx = new bcoin.mtx();
|
|
||||||
|
|
||||||
// Send 10,000 satoshis to ourself.
|
|
||||||
mtx.addOutput({
|
|
||||||
address: keyring.getAddress(),
|
|
||||||
value: 10000
|
|
||||||
});
|
|
||||||
|
|
||||||
// Now that we've created the output, we can do some coin selection (the output
|
|
||||||
// must be added first so we know how much money is needed and also so we can
|
|
||||||
// accurately estimate the size for fee calculation).
|
|
||||||
|
|
||||||
// Select coins from our array and add inputs.
|
|
||||||
// Calculate fee and add a change output.
|
|
||||||
mtx.fund(coins, {
|
|
||||||
// Use a rate of 10,000 satoshis per kb.
|
|
||||||
// With the `fullnode` object, you can
|
|
||||||
// use the fee estimator for this instead
|
|
||||||
// of blindly guessing.
|
|
||||||
rate: 10000,
|
|
||||||
// Send the change back to ourselves.
|
|
||||||
changeAddress: keyring.getAddress()
|
|
||||||
}).then(function() {
|
|
||||||
// Sign input 0
|
|
||||||
mtx.sign(keyring);
|
|
||||||
|
|
||||||
// The transaction should now verify.
|
|
||||||
assert(mtx.verify());
|
|
||||||
|
|
||||||
// Commit our transaction and make it immutable.
|
|
||||||
// This turns it from an MTX into a TX.
|
|
||||||
var tx = mtx.toTX();
|
|
||||||
|
|
||||||
// The transaction should still verify.
|
|
||||||
// Regular transactions require a coin
|
|
||||||
// viewpoint to be passed in.
|
|
||||||
assert(tx.verify(mtx.view));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
Loading…
Reference in New Issue
Block a user