Buck Perley
7 years ago
committed by
GitHub
65 changed files with 22764 additions and 7 deletions
@ -0,0 +1,11 @@ |
|||
ruby '>=2.3.1' |
|||
source 'https://rubygems.org' |
|||
|
|||
# Middleman |
|||
gem 'middleman', '~>4.2.1' |
|||
gem 'middleman-syntax', '~> 3.0.0' |
|||
gem 'middleman-autoprefixer', '~> 2.7.0' |
|||
gem "middleman-sprockets", "~> 4.1.0" |
|||
gem 'rouge', '~> 2.0.5' |
|||
gem 'redcarpet', '~> 3.4.0' |
|||
gem 'nokogiri', '~> 1.6.8' |
@ -0,0 +1,129 @@ |
|||
GEM |
|||
remote: https://rubygems.org/ |
|||
specs: |
|||
activesupport (5.0.1) |
|||
concurrent-ruby (~> 1.0, >= 1.0.2) |
|||
i18n (~> 0.7) |
|||
minitest (~> 5.1) |
|||
tzinfo (~> 1.1) |
|||
addressable (2.5.0) |
|||
public_suffix (~> 2.0, >= 2.0.2) |
|||
autoprefixer-rails (6.6.1) |
|||
execjs |
|||
backports (3.6.8) |
|||
coffee-script (2.4.1) |
|||
coffee-script-source |
|||
execjs |
|||
coffee-script-source (1.12.2) |
|||
compass-import-once (1.0.5) |
|||
sass (>= 3.2, < 3.5) |
|||
concurrent-ruby (1.0.4) |
|||
contracts (0.13.0) |
|||
dotenv (2.2.0) |
|||
erubis (2.7.0) |
|||
execjs (2.7.0) |
|||
fast_blank (1.0.0) |
|||
fastimage (2.0.1) |
|||
addressable (~> 2) |
|||
ffi (1.9.17) |
|||
haml (4.0.7) |
|||
tilt |
|||
hamster (3.0.0) |
|||
concurrent-ruby (~> 1.0) |
|||
hashie (3.5.1) |
|||
i18n (0.7.0) |
|||
kramdown (1.13.2) |
|||
listen (3.0.8) |
|||
rb-fsevent (~> 0.9, >= 0.9.4) |
|||
rb-inotify (~> 0.9, >= 0.9.7) |
|||
memoist (0.15.0) |
|||
middleman (4.2.1) |
|||
coffee-script (~> 2.2) |
|||
compass-import-once (= 1.0.5) |
|||
haml (>= 4.0.5) |
|||
kramdown (~> 1.2) |
|||
middleman-cli (= 4.2.1) |
|||
middleman-core (= 4.2.1) |
|||
sass (>= 3.4.0, < 4.0) |
|||
middleman-autoprefixer (2.7.1) |
|||
autoprefixer-rails (>= 6.5.2, < 7.0.0) |
|||
middleman-core (>= 3.3.3) |
|||
middleman-cli (4.2.1) |
|||
thor (>= 0.17.0, < 2.0) |
|||
middleman-core (4.2.1) |
|||
activesupport (>= 4.2, < 5.1) |
|||
addressable (~> 2.3) |
|||
backports (~> 3.6) |
|||
bundler (~> 1.1) |
|||
contracts (~> 0.13.0) |
|||
dotenv |
|||
erubis |
|||
execjs (~> 2.0) |
|||
fast_blank |
|||
fastimage (~> 2.0) |
|||
hamster (~> 3.0) |
|||
hashie (~> 3.4) |
|||
i18n (~> 0.7.0) |
|||
listen (~> 3.0.0) |
|||
memoist (~> 0.14) |
|||
padrino-helpers (~> 0.13.0) |
|||
parallel |
|||
rack (>= 1.4.5, < 3) |
|||
sass (>= 3.4) |
|||
servolux |
|||
tilt (~> 2.0) |
|||
uglifier (~> 3.0) |
|||
middleman-sprockets (4.1.0) |
|||
middleman-core (~> 4.0) |
|||
sprockets (>= 3.0) |
|||
middleman-syntax (3.0.0) |
|||
middleman-core (>= 3.2) |
|||
rouge (~> 2.0) |
|||
mini_portile2 (2.1.0) |
|||
minitest (5.10.1) |
|||
nokogiri (1.6.8.1) |
|||
mini_portile2 (~> 2.1.0) |
|||
padrino-helpers (0.13.3.3) |
|||
i18n (~> 0.6, >= 0.6.7) |
|||
padrino-support (= 0.13.3.3) |
|||
tilt (>= 1.4.1, < 3) |
|||
padrino-support (0.13.3.3) |
|||
activesupport (>= 3.1) |
|||
parallel (1.10.0) |
|||
public_suffix (2.0.5) |
|||
rack (2.0.1) |
|||
rb-fsevent (0.9.8) |
|||
rb-inotify (0.9.8) |
|||
ffi (>= 0.5.0) |
|||
redcarpet (3.4.0) |
|||
rouge (2.0.7) |
|||
sass (3.4.23) |
|||
servolux (0.12.0) |
|||
sprockets (3.7.1) |
|||
concurrent-ruby (~> 1.0) |
|||
rack (> 1, < 3) |
|||
thor (0.19.4) |
|||
thread_safe (0.3.5) |
|||
tilt (2.0.6) |
|||
tzinfo (1.2.2) |
|||
thread_safe (~> 0.1) |
|||
uglifier (3.0.4) |
|||
execjs (>= 0.3.0, < 3) |
|||
|
|||
PLATFORMS |
|||
ruby |
|||
|
|||
DEPENDENCIES |
|||
middleman (~> 4.2.1) |
|||
middleman-autoprefixer (~> 2.7.0) |
|||
middleman-sprockets (~> 4.1.0) |
|||
middleman-syntax (~> 3.0.0) |
|||
nokogiri (~> 1.6.8) |
|||
redcarpet (~> 3.4.0) |
|||
rouge (~> 2.0.5) |
|||
|
|||
RUBY VERSION |
|||
ruby 2.3.3p222 |
|||
|
|||
BUNDLED WITH |
|||
1.14.5 |
@ -0,0 +1,13 @@ |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
@ -0,0 +1,114 @@ |
|||
<p align="center"> |
|||
<img src="https://raw.githubusercontent.com/lord/img/master/logo-slate.png" alt="Slate: API Documentation Generator" width="226"> |
|||
<br> |
|||
<a href="https://travis-ci.org/lord/slate"><img src="https://travis-ci.org/lord/slate.svg?branch=master" alt="Build Status"></a> |
|||
</p> |
|||
|
|||
<p align="center">Slate helps you create beautiful, intelligent, responsive API documentation.</p> |
|||
|
|||
<p align="center"><img src="https://raw.githubusercontent.com/lord/img/master/screenshot-slate.png" width=700 alt="Screenshot of Example Documentation created with Slate"></p> |
|||
|
|||
<p align="center"><em>The example above was created with Slate. Check it out at <a href="https://lord.github.io/slate">lord.github.io/slate</a>.</em></p> |
|||
|
|||
Features |
|||
------------ |
|||
|
|||
* **Clean, intuitive design** — With Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [Paypal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even in print. |
|||
|
|||
* **Everything on a single page** — Gone are the days when your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy. |
|||
|
|||
* **Slate is just Markdown** — When you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks. |
|||
|
|||
* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with Github Flavored Markdown. |
|||
|
|||
* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required. |
|||
|
|||
* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents. |
|||
|
|||
* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public Github repository. Not only does this mean you get free hosting for your docs with Github Pages, but it also makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere. |
|||
|
|||
Getting started with Slate is super easy! Simply fork this repository and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](http://lord.github.io/slate). |
|||
|
|||
Getting Started with Slate |
|||
------------------------------ |
|||
|
|||
### Prerequisites |
|||
|
|||
You're going to need: |
|||
|
|||
- **Linux or OS X** — Windows may work, but is unsupported. |
|||
- **Ruby, version 2.3.1 or newer** |
|||
- **Bundler** — If Ruby is already installed, but the `bundle` command doesn't work, just run `gem install bundler` in a terminal. |
|||
|
|||
### Getting Set Up |
|||
|
|||
1. Fork this repository on Github. |
|||
2. Clone *your forked repository* (not our original one) to your hard drive with `git clone https://github.com/YOURUSERNAME/slate.git` |
|||
3. `cd slate` |
|||
4. Initialize and start Slate. You can either do this locally, or with Vagrant: |
|||
|
|||
```shell |
|||
# either run this to run locally |
|||
bundle install |
|||
bundle exec middleman server |
|||
|
|||
# OR run this to run with vagrant |
|||
vagrant up |
|||
``` |
|||
|
|||
You can now see the docs at http://localhost:4567. Whoa! That was fast! |
|||
|
|||
Now that Slate is all set up on your machine, you'll probably want to learn more about [editing Slate markdown](https://github.com/lord/slate/wiki/Markdown-Syntax), or [how to publish your docs](https://github.com/lord/slate/wiki/Deploying-Slate). |
|||
|
|||
If you'd prefer to use Docker, instructions are available [in the wiki](https://github.com/lord/slate/wiki/Docker). |
|||
|
|||
### Note on JavaScript Runtime |
|||
|
|||
For those who don't have JavaScript runtime or are experiencing JavaScript runtime issues with ExecJS, it is recommended to add the [rubyracer gem](https://github.com/cowboyd/therubyracer) to your gemfile and run `bundle` again. |
|||
|
|||
Companies Using Slate |
|||
--------------------------------- |
|||
|
|||
* [NASA](https://api.nasa.gov) |
|||
* [IBM](https://docs.cloudant.com/api.html) |
|||
* [Sony](http://developers.cimediacloud.com) |
|||
* [Best Buy](https://bestbuyapis.github.io/api-documentation/) |
|||
* [Travis-CI](https://docs.travis-ci.com/api/) |
|||
* [Greenhouse](https://developers.greenhouse.io/harvest.html) |
|||
* [Woocommerce](http://woocommerce.github.io/woocommerce-rest-api-docs/) |
|||
* [Appium](http://appium.io/slate/en/master) |
|||
* [Dwolla](https://docs.dwolla.com/) |
|||
* [Clearbit](https://clearbit.com/docs) |
|||
* [Coinbase](https://developers.coinbase.com/api) |
|||
* [Parrot Drones](http://developer.parrot.com/docs/bebop/) |
|||
* [Fidor Bank](http://docs.fidor.de/) |
|||
* [Scale](https://docs.scaleapi.com/) |
|||
|
|||
You can view more in [the list on the wiki](https://github.com/lord/slate/wiki/Slate-in-the-Wild). |
|||
|
|||
Need Help? Found a bug? |
|||
-------------------- |
|||
|
|||
[Submit an issue](https://github.com/lord/slate/issues) to the Slate Github if you need any help. And, of course, feel free to submit pull requests with bug fixes or changes. |
|||
|
|||
Contributors |
|||
-------------------- |
|||
|
|||
Slate was built by [Robert Lord](https://lord.io) while interning at [TripIt](https://www.tripit.com/). |
|||
|
|||
Thanks to the following people who have submitted major pull requests: |
|||
|
|||
- [@chrissrogers](https://github.com/chrissrogers) |
|||
- [@bootstraponline](https://github.com/bootstraponline) |
|||
- [@realityking](https://github.com/realityking) |
|||
- [@cvkef](https://github.com/cvkef) |
|||
|
|||
Also, thanks to [Sauce Labs](http://saucelabs.com) for sponsoring the development of the responsive styles. |
|||
|
|||
Special Thanks |
|||
-------------------- |
|||
- [Middleman](https://github.com/middleman/middleman) |
|||
- [jquery.tocify.js](https://github.com/gfranko/jquery.tocify.js) |
|||
- [middleman-syntax](https://github.com/middleman/middleman-syntax) |
|||
- [middleman-gh-pages](https://github.com/edgecase/middleman-gh-pages) |
|||
- [Font Awesome](http://fortawesome.github.io/Font-Awesome/) |
@ -0,0 +1,57 @@ |
|||
# Unique header generation |
|||
require './lib/unique_head.rb' |
|||
|
|||
# Markdown |
|||
set :markdown_engine, :redcarpet |
|||
set :markdown, |
|||
fenced_code_blocks: true, |
|||
smartypants: true, |
|||
disable_indented_code_blocks: true, |
|||
prettify: true, |
|||
tables: true, |
|||
with_toc_data: true, |
|||
no_intra_emphasis: true, |
|||
renderer: UniqueHeadCounter |
|||
|
|||
# Assets |
|||
set :css_dir, 'stylesheets' |
|||
set :js_dir, 'javascripts' |
|||
set :images_dir, 'images' |
|||
set :fonts_dir, 'fonts' |
|||
|
|||
# Activate the syntax highlighter |
|||
activate :syntax |
|||
ready do |
|||
require './lib/multilang.rb' |
|||
end |
|||
|
|||
activate :sprockets |
|||
|
|||
activate :autoprefixer do |config| |
|||
config.browsers = ['last 2 version', 'Firefox ESR'] |
|||
config.cascade = false |
|||
config.inline = true |
|||
end |
|||
|
|||
# Github pages require relative links |
|||
activate :relative_assets |
|||
set :relative_links, true |
|||
|
|||
# Build Configuration |
|||
configure :build do |
|||
# If you're having trouble with Middleman hanging, commenting |
|||
# out the following two lines has been known to help |
|||
activate :minify_css |
|||
activate :minify_javascript |
|||
# activate :relative_assets |
|||
# activate :asset_hash |
|||
# activate :gzip |
|||
end |
|||
|
|||
# Deploy Configuration |
|||
# If you want Middleman to listen on a different port, you can set that below |
|||
set :port, 4567 |
|||
|
|||
helpers do |
|||
require './lib/toc_data.rb' |
|||
end |
@ -0,0 +1,148 @@ |
|||
{ |
|||
"IcoMoonType": "selection", |
|||
"icons": [ |
|||
{ |
|||
"icon": { |
|||
"paths": [ |
|||
"M438.857 73.143q119.429 0 220.286 58.857t159.714 159.714 58.857 220.286-58.857 220.286-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857zM512 785.714v-108.571q0-8-5.143-13.429t-12.571-5.429h-109.714q-7.429 0-13.143 5.714t-5.714 13.143v108.571q0 7.429 5.714 13.143t13.143 5.714h109.714q7.429 0 12.571-5.429t5.143-13.429zM510.857 589.143l10.286-354.857q0-6.857-5.714-10.286-5.714-4.571-13.714-4.571h-125.714q-8 0-13.714 4.571-5.714 3.429-5.714 10.286l9.714 354.857q0 5.714 5.714 10t13.714 4.286h105.714q8 0 13.429-4.286t6-10z" |
|||
], |
|||
"attrs": [], |
|||
"isMulticolor": false, |
|||
"tags": [ |
|||
"exclamation-circle" |
|||
], |
|||
"defaultCode": 61546, |
|||
"grid": 14 |
|||
}, |
|||
"attrs": [], |
|||
"properties": { |
|||
"id": 100, |
|||
"order": 4, |
|||
"prevSize": 28, |
|||
"code": 58880, |
|||
"name": "exclamation-sign", |
|||
"ligatures": "" |
|||
}, |
|||
"setIdx": 0, |
|||
"iconIdx": 0 |
|||
}, |
|||
{ |
|||
"icon": { |
|||
"paths": [ |
|||
"M585.143 786.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-54.857v-292.571q0-8-5.143-13.143t-13.143-5.143h-182.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h54.857v182.857h-54.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h256q8 0 13.143-5.143t5.143-13.143zM512 274.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-109.714q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h109.714q8 0 13.143-5.143t5.143-13.143zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z" |
|||
], |
|||
"attrs": [], |
|||
"isMulticolor": false, |
|||
"tags": [ |
|||
"info-circle" |
|||
], |
|||
"defaultCode": 61530, |
|||
"grid": 14 |
|||
}, |
|||
"attrs": [], |
|||
"properties": { |
|||
"id": 85, |
|||
"order": 3, |
|||
"name": "info-sign", |
|||
"prevSize": 28, |
|||
"code": 58882 |
|||
}, |
|||
"setIdx": 0, |
|||
"iconIdx": 2 |
|||
}, |
|||
{ |
|||
"icon": { |
|||
"paths": [ |
|||
"M733.714 419.429q0-16-10.286-26.286l-52-51.429q-10.857-10.857-25.714-10.857t-25.714 10.857l-233.143 232.571-129.143-129.143q-10.857-10.857-25.714-10.857t-25.714 10.857l-52 51.429q-10.286 10.286-10.286 26.286 0 15.429 10.286 25.714l206.857 206.857q10.857 10.857 25.714 10.857 15.429 0 26.286-10.857l310.286-310.286q10.286-10.286 10.286-25.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z" |
|||
], |
|||
"attrs": [], |
|||
"isMulticolor": false, |
|||
"tags": [ |
|||
"check-circle" |
|||
], |
|||
"defaultCode": 61528, |
|||
"grid": 14 |
|||
}, |
|||
"attrs": [], |
|||
"properties": { |
|||
"id": 83, |
|||
"order": 9, |
|||
"prevSize": 28, |
|||
"code": 58886, |
|||
"name": "ok-sign" |
|||
}, |
|||
"setIdx": 0, |
|||
"iconIdx": 6 |
|||
}, |
|||
{ |
|||
"icon": { |
|||
"paths": [ |
|||
"M658.286 475.429q0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857 75.143 180.857 180.857 75.143 180.857-75.143 75.143-180.857zM950.857 950.857q0 29.714-21.714 51.429t-51.429 21.714q-30.857 0-51.429-21.714l-196-195.429q-102.286 70.857-228 70.857-81.714 0-156.286-31.714t-128.571-85.714-85.714-128.571-31.714-156.286 31.714-156.286 85.714-128.571 128.571-85.714 156.286-31.714 156.286 31.714 128.571 85.714 85.714 128.571 31.714 156.286q0 125.714-70.857 228l196 196q21.143 21.143 21.143 51.429z" |
|||
], |
|||
"width": 951, |
|||
"attrs": [], |
|||
"isMulticolor": false, |
|||
"tags": [ |
|||
"search" |
|||
], |
|||
"defaultCode": 61442, |
|||
"grid": 14 |
|||
}, |
|||
"attrs": [], |
|||
"properties": { |
|||
"id": 2, |
|||
"order": 1, |
|||
"prevSize": 28, |
|||
"code": 58887, |
|||
"name": "icon-search" |
|||
}, |
|||
"setIdx": 0, |
|||
"iconIdx": 7 |
|||
} |
|||
], |
|||
"height": 1024, |
|||
"metadata": { |
|||
"name": "slate", |
|||
"license": "SIL OFL 1.1" |
|||
}, |
|||
"preferences": { |
|||
"showGlyphs": true, |
|||
"showQuickUse": true, |
|||
"showQuickUse2": true, |
|||
"showSVGs": true, |
|||
"fontPref": { |
|||
"prefix": "icon-", |
|||
"metadata": { |
|||
"fontFamily": "slate", |
|||
"majorVersion": 1, |
|||
"minorVersion": 0, |
|||
"description": "Based on FontAwesome", |
|||
"license": "SIL OFL 1.1" |
|||
}, |
|||
"metrics": { |
|||
"emSize": 1024, |
|||
"baseline": 6.25, |
|||
"whitespace": 50 |
|||
}, |
|||
"resetPoint": 58880, |
|||
"showSelector": false, |
|||
"selector": "class", |
|||
"classSelector": ".icon", |
|||
"showMetrics": false, |
|||
"showMetadata": true, |
|||
"showVersion": true, |
|||
"ie7": false |
|||
}, |
|||
"imagePref": { |
|||
"prefix": "icon-", |
|||
"png": true, |
|||
"useClassSelector": true, |
|||
"color": 4473924, |
|||
"bgColor": 16777215 |
|||
}, |
|||
"historySize": 100, |
|||
"showCodes": true, |
|||
"gridSize": 16, |
|||
"showLiga": false |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
module Multilang |
|||
def block_code(code, full_lang_name) |
|||
if full_lang_name |
|||
parts = full_lang_name.split('--') |
|||
rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified |
|||
super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match| |
|||
match + " tab-" + full_lang_name |
|||
end |
|||
else |
|||
super(code, full_lang_name) |
|||
end |
|||
end |
|||
end |
|||
|
|||
require 'middleman-core/renderers/redcarpet' |
|||
Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang |
@ -0,0 +1,30 @@ |
|||
require 'nokogiri' |
|||
|
|||
def toc_data(page_content) |
|||
html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content) |
|||
|
|||
# get a flat list of headers |
|||
headers = [] |
|||
html_doc.css('h1, h2, h3').each do |header| |
|||
headers.push({ |
|||
id: header.attribute('id').to_s, |
|||
content: header.children, |
|||
level: header.name[1].to_i, |
|||
children: [] |
|||
}) |
|||
end |
|||
|
|||
[3,2].each do |header_level| |
|||
header_to_nest = nil |
|||
headers = headers.reject do |header| |
|||
if header[:level] == header_level |
|||
header_to_nest[:children].push header if header_to_nest |
|||
true |
|||
else |
|||
header_to_nest = header if header[:level] < header_level |
|||
false |
|||
end |
|||
end |
|||
end |
|||
headers |
|||
end |
@ -0,0 +1,17 @@ |
|||
# Unique header generation |
|||
require 'middleman-core/renderers/redcarpet' |
|||
class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML |
|||
def initialize |
|||
super |
|||
@head_count = {} |
|||
end |
|||
def header(text, header_level) |
|||
friendly_text = text.parameterize |
|||
@head_count[friendly_text] ||= 0 |
|||
@head_count[friendly_text] += 1 |
|||
if @head_count[friendly_text] > 1 |
|||
friendly_text += "-#{@head_count[friendly_text]}" |
|||
end |
|||
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>" |
|||
end |
|||
end |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 96 B |
@ -0,0 +1,106 @@ |
|||
# Configuring Clients |
|||
|
|||
## Default Listeners |
|||
```shell--visible |
|||
# With curl you just send HTTP Requests based on further docs |
|||
# Only thing to have in mind is Authentication, which is described in Auth section. |
|||
|
|||
curl http://127.0.0.1:18332/ # will get info from testnet |
|||
``` |
|||
|
|||
By default API listens on these addresses: |
|||
|
|||
Network | API Port |
|||
--------- | ----------- |
|||
main | 8332 |
|||
testnet | 18332 |
|||
regtest | 48332 |
|||
simnet | 18556 |
|||
|
|||
You can interact with bcoin with REST Api as well as RPC, |
|||
there are couple of ways you can use API. |
|||
|
|||
- `bcoin cli` - has almost all methods described to be used. |
|||
- `javascript` - Clients used by `bcoin cli` can be used directly from javascript |
|||
- `curl` - or you can use direct HTTP calls for invoking REST/RPC API calls. |
|||
|
|||
## Configuring BCOIN CLI |
|||
|
|||
```shell--visible |
|||
# You can use config file |
|||
bcoin cli --config /full/path/to/bcoin.conf |
|||
|
|||
# Or with prefix (which will later load bcoin.conf file from the directory) |
|||
bcoin cli --prefix /full/path/to/bcoin/dir |
|||
|
|||
# You can configure it by passing arguments: |
|||
bcoin cli --network=regtest info |
|||
bcoin cli info --network=regtest |
|||
|
|||
# Or use ENV variables (Starting with BCOIN_) |
|||
export BCOIN_NETWORK=regtest |
|||
export BCOIN_API_KEY=yoursecret |
|||
bcoin cli info |
|||
``` |
|||
|
|||
`bcoin cli` can be configured with many params: |
|||
|
|||
### General configurations are: |
|||
|
|||
Config | Options | Description |
|||
--------- | ----------- | ----------- |
|||
prefix | dir path | This accepts directory where DBs and `bcoin.conf` are located. |
|||
network | `main`, `testnet`, `regtest` | This will configure which network to load, also where to look for config file |
|||
uri, url | Base HTTP URI | This can be used for custom port |
|||
api-key | secret | Secret used by RPC for auth. |
|||
|
|||
### Wallet Specific |
|||
|
|||
Config | Options | Description |
|||
--------- | ----------- | ----------- |
|||
id | primary, custom | specify which account to use by default |
|||
token | token str | Token specific wallet |
|||
|
|||
<aside class="notice"> |
|||
Some commands might accept additional parameters. |
|||
</aside> |
|||
|
|||
## Using Javascript Client |
|||
|
|||
```javascript--visible |
|||
const bcoin = require('bcoin'); |
|||
const Client = bcoin.http.Client; |
|||
const Wallet = bcoin.http.Wallet; |
|||
|
|||
const client = new Client({ |
|||
network: 'testnet', |
|||
uri: 'http://localhost:18332' |
|||
}); |
|||
|
|||
const wallet = new Wallet({ |
|||
network: 'testnet', |
|||
uri: 'http://localhost:18332', |
|||
id: 'primary' |
|||
}); |
|||
``` |
|||
|
|||
You can also use api with Javascript Library (used by `bcoin cli`). |
|||
There are two objects: `bcoin.http.Client` for general API and `bcoin.http.Wallet` for wallet API. |
|||
|
|||
`bcoin.http.Client` options: |
|||
|
|||
Config | Type | Description |
|||
--------- | ----------- | ----------- |
|||
network | `main`, `testnet`, `regtest` | Network to use (doesn't lookup configs by itself) |
|||
uri | String | URI of the service |
|||
apiKey | String | api secret |
|||
|
|||
`bcoin.http.Wallet` options: |
|||
|
|||
Config | Type | Description |
|||
--------- | ----------- | ----------- |
|||
network | `main`, `testnet`, `regtest` | Network to use (doesn't lookup configs by itself) |
|||
uri | String | URI of the service |
|||
apiKey | String | api secret |
|||
id | primary, custom | specify which account to use by default |
|||
token | token str | Token specific wallet |
@ -0,0 +1,218 @@ |
|||
# Coin |
|||
Getting coin information via APi. |
|||
|
|||
*Coin stands for UTXO* |
|||
|
|||
<aside class="info"> |
|||
You need to enable <code>index-tx</code> and <code>index-address</code> in order |
|||
to lookup coins by transaction hashes and addresses, respectively. |
|||
</aside> |
|||
|
|||
|
|||
## Get coin by Outpoint |
|||
|
|||
```javascript |
|||
let hash, index; |
|||
``` |
|||
|
|||
```shell--vars |
|||
hash='c13039f53247f9ca14206da079bcf738d91bc60e251ac9ebaba9ea9a862d9092'; |
|||
index=0; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/coin/$hash/$index |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli coin $hash $index |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const coin = await client.getCoin(hash, index); |
|||
|
|||
console.log(coin); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
{ |
|||
"version": 1, |
|||
"height": 100019, |
|||
"value": 144709200, |
|||
"script": "76a9148fc80aadf127f6f92b6ed33404b110f851c8eca188ac", |
|||
"address": "mtdCZdNYny2U7met3umk47SoA7HMZGfsa2", |
|||
"coinbase": false, |
|||
"hash": "c13039f53247f9ca14206da079bcf738d91bc60e251ac9ebaba9ea9a862d9092", |
|||
"index": 0 |
|||
} |
|||
``` |
|||
|
|||
Get coin by outpoint (hash and index). Returns coin in bcoin coin json format. |
|||
|
|||
### HTTP Request |
|||
`GET /coin/:hash/:index` |
|||
|
|||
### URL Parameters |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
:hash | Hash of tx |
|||
:index | Output's index in tx |
|||
|
|||
|
|||
|
|||
## Get coins by address |
|||
|
|||
```javascript |
|||
let address; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address='n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/coin/address/$address |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli coin $address |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const coins = await client.getCoinsByAddress(address); |
|||
|
|||
console.log(coins); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"version": 1, |
|||
"height": 502, |
|||
"value": 275391, |
|||
"script": "76a914edb1dfaf6e0b39449da811275386edf2eb54baba88ac", |
|||
"address": "n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr", |
|||
"coinbase": false, |
|||
"hash": "86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9", |
|||
"index": 1 |
|||
} |
|||
] |
|||
``` |
|||
|
|||
Get coin objects array by address. |
|||
|
|||
### HTTP Request |
|||
`GET /coin/address/:address` |
|||
|
|||
### URL Parameters |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
:address | bitcoin address |
|||
|
|||
|
|||
|
|||
## Get coins by addresses |
|||
|
|||
```javascript |
|||
let address0, address1; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address0='n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr'; |
|||
address1='mwLHWwWPDwtCBZA7Ltg9QSzKK5icdCU5rb'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/coin/address \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "addresses":[ "'$address0'", "'$address1'" ]}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
No CLI Option. |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const coins = await client.getCoinsByAddresses([address0, address1]); |
|||
|
|||
console.log(coins); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"version": 1, |
|||
"height": 502, |
|||
"value": 275391, |
|||
"script": "76a914edb1dfaf6e0b39449da811275386edf2eb54baba88ac", |
|||
"address": "n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr", |
|||
"coinbase": false, |
|||
"hash": "86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9", |
|||
"index": 1 |
|||
}, |
|||
{ |
|||
"version": 1, |
|||
"height": 500, |
|||
"value": 1095497, |
|||
"script": "76a914ad7d7b9ac5260ad13fa55e06143283f5b36495f788ac", |
|||
"address": "mwLHWwWPDwtCBZA7Ltg9QSzKK5icdCU5rb", |
|||
"coinbase": false, |
|||
"hash": "4692772a73ea834c836915089acf97f2c790380a2b8fd32f82729da72545d8c5", |
|||
"index": 0 |
|||
} |
|||
] |
|||
``` |
|||
|
|||
Get coins by addresses, |
|||
returns array of coin objects. |
|||
|
|||
### HTTP Request |
|||
`POST /coin/address` |
|||
|
|||
### POST Parameters (JSON) |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
addresses | List of bitcoin addresses |
@ -0,0 +1,4 @@ |
|||
# Errors |
|||
Any errors will be returned with an http status code other than 200, containing a JSON object in the form: |
|||
|
|||
`{"error": { message: "message" } }` |
@ -0,0 +1,294 @@ |
|||
# Node |
|||
|
|||
## JSON-RPC Requests |
|||
|
|||
Route for JSON-RPC requests, most of which mimic the bitcoind RPC calls completely. |
|||
|
|||
```shell--curl |
|||
curl $url \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "getblockchaininfo", "params": [] }' |
|||
``` |
|||
|
|||
### HTTP Request |
|||
`POST /` |
|||
|
|||
More about RPC Requests in RPC Docs. |
|||
|
|||
## Get server info |
|||
|
|||
```shell--curl |
|||
curl $url/ |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli info |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
const info = await client.getInfo(); |
|||
|
|||
console.log(info); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
{ |
|||
"version": "v1.0.0-beta.14", |
|||
"network": "testnet", |
|||
"chain": { |
|||
"height": 1157058, |
|||
"tip": "00000000000002ac70408966be53a1e01e7e014a3d4f1f275201c751de7d6e77", |
|||
"progress": 1 |
|||
}, |
|||
"pool": { |
|||
"host": "203.0.113.114", |
|||
"port": 18333, |
|||
"agent": "/bcoin:v1.0.0-beta.14/", |
|||
"services": "1001", |
|||
"outbound": 8, |
|||
"inbound": 0 |
|||
}, |
|||
"mempool": { |
|||
"tx": 39, |
|||
"size": 121512 |
|||
}, |
|||
"time": { |
|||
"uptime": 7403, |
|||
"system": 1502381034, |
|||
"adjusted": 1502381035, |
|||
"offset": 1 |
|||
}, |
|||
"memory": { |
|||
"total": 87, |
|||
"jsHeap": 23, |
|||
"jsHeapTotal": 30, |
|||
"nativeHeap": 56, |
|||
"external": 8 |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Get server Info. |
|||
|
|||
### HTTP Request |
|||
<p>Get server info. No params.</p> |
|||
|
|||
`GET /` |
|||
|
|||
No Params. |
|||
|
|||
|
|||
## Get mempool snapshot |
|||
|
|||
```shell--curl |
|||
curl $url/mempool |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli mempool |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
const mempoolTxs = await client.getMempool(); |
|||
|
|||
console.log(mempoolTxs); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
[ |
|||
"9fee8350a3cc2f5bfa9d90f008af0bbc22d84aa5b1242da2f3479935f597c9ed", |
|||
"d3bd772f3b369e2e04b9b928e40dddded5ee1448b9d1ee0b6a13e6c2ae283f6a", |
|||
... |
|||
] |
|||
``` |
|||
|
|||
Get mempool snapshot (array of json txs). |
|||
|
|||
### HTTP Request |
|||
`GET /mempool` |
|||
|
|||
No Params. |
|||
|
|||
|
|||
## Get block by hash or height |
|||
|
|||
```javascript |
|||
let blockHash, blockHeight; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockHash='00000000cabd2d0245add40f335bab18d3e837eccf868b64aabbbbac74fb21e0'; |
|||
blockHeight='1500'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/block/$blockHash # by hash |
|||
curl $url/block/$blockHeight # by height |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli block $blockHash # by hash |
|||
bcoin cli block $blockHeight # by height |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
const blockByHash = await client.getBlock(blockHash); |
|||
const blockByHeight = await client.getBlock(blockHeight); |
|||
|
|||
console.log(blockByHash, blockByHeight); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
{ |
|||
"hash": "00000000cabd2d0245add40f335bab18d3e837eccf868b64aabbbbac74fb21e0", |
|||
"height": 1500, |
|||
"version": 1, |
|||
"prevBlock": "00000000f651e7fe6d9a4845dcf40f5642216e59054453a4368a73a7295f9f3d", |
|||
"merkleRoot": "e3e4590784a828967e6d9319eca2915c1860a63167449f9605e649a0aafe6d0a", |
|||
"time": 1337966228, |
|||
"bits": 486604799, |
|||
"nonce": 2671491584, |
|||
"txs": [ |
|||
{ |
|||
"hash": "e3e4590784a828967e6d9319eca2915c1860a63167449f9605e649a0aafe6d0a", |
|||
"witnessHash": "e3e4590784a828967e6d9319eca2915c1860a63167449f9605e649a0aafe6d0a", |
|||
"fee": 0, |
|||
"rate": 0, |
|||
"mtime": 1502382669, |
|||
"index": 0, |
|||
"version": 1, |
|||
"flag": 1, |
|||
"inputs": [ |
|||
{ |
|||
"prevout": { |
|||
"hash": "0000000000000000000000000000000000000000000000000000000000000000", |
|||
"index": 4294967295 |
|||
}, |
|||
"script": "0494bebf4f0108172f503253482f49636549726f6e2d51432d6d696e65722f", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"address": null |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"value": 5000000000, |
|||
"script": "21032fd2666c8d5ffae0147acc0b9628160652679663397e911170ebaf1e26358abfac", |
|||
"address": "mtohBeScUtM2ndcmmpSV8o2jcvmknp1Mpy" |
|||
} |
|||
], |
|||
"locktime": 0 |
|||
} |
|||
] |
|||
} |
|||
``` |
|||
|
|||
Returns block info by block hash or height. |
|||
|
|||
### HTTP Request |
|||
`GET /block/:blockhashOrHeight` |
|||
|
|||
|
|||
### URL Parameters |
|||
|
|||
Parameter | Description |
|||
--------- | ----------- |
|||
:blockhashOrHeight | Hash or Height of block |
|||
|
|||
|
|||
|
|||
## Broadcast transaction |
|||
```javascript |
|||
let tx; |
|||
``` |
|||
|
|||
```shell--vars |
|||
tx='0100000001ff2a3afc3a8133a3bfeedd391bc3cff39d47fe4e3caee492a93f92edff76b9d4000000006a47304402204cc6a35cb3d3d976cb10e3c98df66aba29b5efc7b5ecdbc0f4ed949aa64235f20220512fce2d63739012094f12c3a9402919b32149c32d4d71a3448d4695ae8e3dc601210325c9abd8916d6e5ba0b3c501a70c0186f3bf6e4567922b9d83ae205d1d9e9affffffffff0244cff505000000001976a91423f5580d600bcfe5b99d9fe737530fd8b32492a088ac00111024010000001976a91473f3ecd665da93701358bd957393b8085c1aa2d988ac00000000'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/broadcast \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "tx": "'$tx'" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli broadcast $txhex |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet', |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const result = await client.broadcast(tx); |
|||
|
|||
console.log(result); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
{ |
|||
"success": true |
|||
} |
|||
``` |
|||
|
|||
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. |
|||
|
|||
### HTTP Request |
|||
`POST /broadcast` |
|||
|
|||
### POST Parameters (JSON) |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
tx | transaction hash |
@ -0,0 +1,52 @@ |
|||
# RPC Calls - Node |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "methodname", "params": [...] "id": "some-id" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc params... |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('MethodName', [ ...params ]); |
|||
|
|||
// RES will return "result" part of the object, not the id or error |
|||
// error will be thrown. |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
> Further examples will only include "result" part. |
|||
|
|||
```json |
|||
{"result": resultObject ,"error": errorObject, "id": passedID} |
|||
``` |
|||
|
|||
|
|||
Bcoin rpc calls mimic Bitcoin Core's RPC. |
|||
This is documentation how to use it with `bcoin`. |
|||
|
|||
RPC Calls are accepted at: |
|||
`POST /` |
|||
|
|||
*Note: bcoin cli rpc and javascript will return error OR result.* |
|||
|
|||
|
|||
### POST Parameters RPC |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
method | Name of the RPC call |
|||
params | Parameters accepted by method |
|||
id | Will be returned with the response (Shouldn't be object) |
@ -0,0 +1,581 @@ |
|||
# RPC Calls - Block |
|||
|
|||
## getblockchaininfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "getblockchaininfo" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getblockchaininfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblockchaininfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"chain": "test", |
|||
"blocks": 1178402, |
|||
"headers": 1178402, |
|||
"bestblockhash": "0000000000000dd897f549915ba7099b6d4f86f4512801d617a7c0c655827d08", |
|||
"difficulty": 1048576, |
|||
"mediantime": 1502814951, |
|||
"verificationprogress": 1, |
|||
"chainwork": "00000000000000000000000000000000000000000000002976ca78529498e335", |
|||
"pruned": false, |
|||
"softforks": [ |
|||
{ |
|||
"id": "bip34", |
|||
"version": 2, |
|||
"reject": { |
|||
"status": true |
|||
} |
|||
}, |
|||
{ |
|||
"id": "bip66", |
|||
"version": 3, |
|||
"reject": { |
|||
"status": true |
|||
} |
|||
}, |
|||
{ |
|||
"id": "bip65", |
|||
"version": 4, |
|||
"reject": { |
|||
"status": true |
|||
} |
|||
} |
|||
], |
|||
"bip9_softforks": { |
|||
"csv": { |
|||
"status": "active", |
|||
"bit": 0, |
|||
"startTime": 1456790400, |
|||
"timeout": 1493596800 |
|||
}, |
|||
"segwit": { |
|||
"status": "active", |
|||
"bit": 1, |
|||
"startTime": 1462060800, |
|||
"timeout": 1493596800 |
|||
}, |
|||
"segsignal": { |
|||
"status": "defined", |
|||
"bit": 4, |
|||
"startTime": 4294967295, |
|||
"timeout": 4294967295 |
|||
}, |
|||
"testdummy": { |
|||
"status": "failed", |
|||
"bit": 28, |
|||
"startTime": 1199145601, |
|||
"timeout": 1230767999 |
|||
} |
|||
}, |
|||
"pruneheight": null |
|||
} |
|||
``` |
|||
|
|||
Returns blockchain information. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getbestblockhash |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "getbestblockhash" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getbestblockhash |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getbestblockhash'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"0000000000000225f8332239fe00b74c65f916ff71dde5dee33b72ddd3b0e237" |
|||
``` |
|||
|
|||
Returns Block Hash of the tip. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getblockcount |
|||
|
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "getblockcount" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getbestblockhash |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblockcount'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
1178418 |
|||
``` |
|||
|
|||
Returns block count. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. |||| |
|||
|
|||
|
|||
|
|||
## getblock |
|||
|
|||
```javascript |
|||
let blockhash, details, verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockhash='00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37'; |
|||
verbose=1; |
|||
details=0; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getblock", |
|||
"params": [ "'$blockhash'", "'$verbose'", "'$details'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getblock $blockhash $verbose $details |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblock', [ blockhash, verbose, details ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"hash": "00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37", |
|||
"confirmations": 1177921, |
|||
"strippedsize": 2499, |
|||
"size": 2499, |
|||
"weight": 9996, |
|||
"height": 502, |
|||
"version": 1, |
|||
"versionHex": "00000001", |
|||
"merkleroot": "4f7a9087973b891fc86cc59fd9c2cb696f7a813360d3553626dc6c38909f9571", |
|||
"coinbase": "3337346bde777ade327922b5deef5fb7f88e98cecb22", |
|||
"tx": [ |
|||
"2a69b021fc6cbd61260767302781c85fb0873acf18980ea6187fc868e4a3e3f9", |
|||
"c61f2ef26bb08dcf1e16db4fece56ac92a3acac24e4dac90315e5c0ad6af67e6", |
|||
"ed8c8213cc2d214ad2f293caae99e26e2c59d158f3eda5d9c1292e0961e20e76", |
|||
"21da008d1fddc1a067d2d6cd9bb6e78acb5bdc9560252c17cfd59c331dd5c2cf", |
|||
"90cc439e0a03109c33c966d92ccd18b0509ef678458d85a097397ee9bfbd54c0", |
|||
"1d67f7466fd711f8106fb437cb6a59b7ccd14cd6069edc132627a9fb01d4f09c", |
|||
"402450f5b4cd794d4198f940977bf4291ce25a7ff8b157adf71c07ed065db380", |
|||
"0173a5d24d393127d5e6fc043ff1a00dafc6a2777143cb98a803a0b6e8cd02c7", |
|||
"86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9" |
|||
], |
|||
"time": 1296746959, |
|||
"mediantime": 1296746728, |
|||
"bits": 486604799, |
|||
"difficulty": 1, |
|||
"chainwork": "000000000000000000000000000000000000000000000000000001f701f701f7", |
|||
"previousblockhash": "00000000c7f50b6dfac8b8a59e11b7e62f07fdef20597089b9c5d64ebfe6d682", |
|||
"nextblockhash": "00000000f797111d0f67d7f08346757948e7c469f14cddbd1c3d0217306bf003" |
|||
} |
|||
``` |
|||
|
|||
Returns information about block. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockhash | Required | Hash of the block |
|||
2 | verbose | true | If set to false, it will return hex of the block |
|||
3 | details | false | If set to true, it will return transaction details too. |
|||
|
|||
|
|||
|
|||
## getblockbyheight |
|||
|
|||
```javascript |
|||
let blockhash, details, verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockheight=502; |
|||
verbose=1; |
|||
details=0; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getblockbyheight", |
|||
"params": [ "'$blockheight'", "'$verbose'", "'$details'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getblockbyheight $blockheight $verbose $details |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblockbyheight', [ blockheight, verbose, details ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"hash": "00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37", |
|||
"confirmations": 1177921, |
|||
"strippedsize": 2499, |
|||
"size": 2499, |
|||
"weight": 9996, |
|||
"height": 502, |
|||
"version": 1, |
|||
"versionHex": "00000001", |
|||
"merkleroot": "4f7a9087973b891fc86cc59fd9c2cb696f7a813360d3553626dc6c38909f9571", |
|||
"coinbase": "3337346bde777ade327922b5deef5fb7f88e98cecb22", |
|||
"tx": [ |
|||
"2a69b021fc6cbd61260767302781c85fb0873acf18980ea6187fc868e4a3e3f9", |
|||
"c61f2ef26bb08dcf1e16db4fece56ac92a3acac24e4dac90315e5c0ad6af67e6", |
|||
"ed8c8213cc2d214ad2f293caae99e26e2c59d158f3eda5d9c1292e0961e20e76", |
|||
"21da008d1fddc1a067d2d6cd9bb6e78acb5bdc9560252c17cfd59c331dd5c2cf", |
|||
"90cc439e0a03109c33c966d92ccd18b0509ef678458d85a097397ee9bfbd54c0", |
|||
"1d67f7466fd711f8106fb437cb6a59b7ccd14cd6069edc132627a9fb01d4f09c", |
|||
"402450f5b4cd794d4198f940977bf4291ce25a7ff8b157adf71c07ed065db380", |
|||
"0173a5d24d393127d5e6fc043ff1a00dafc6a2777143cb98a803a0b6e8cd02c7", |
|||
"86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9" |
|||
], |
|||
"time": 1296746959, |
|||
"mediantime": 1296746728, |
|||
"bits": 486604799, |
|||
"difficulty": 1, |
|||
"chainwork": "000000000000000000000000000000000000000000000000000001f701f701f7", |
|||
"previousblockhash": "00000000c7f50b6dfac8b8a59e11b7e62f07fdef20597089b9c5d64ebfe6d682", |
|||
"nextblockhash": "00000000f797111d0f67d7f08346757948e7c469f14cddbd1c3d0217306bf003" |
|||
} |
|||
``` |
|||
|
|||
Returns information about block by height. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockheight | Required | height of the block in the blockchain. |
|||
2 | verbose | true | If set to false, it will return hex of the block. |
|||
3 | details | false | If set to true, it will return transaction details too. |
|||
|
|||
|
|||
|
|||
## getblockhash |
|||
|
|||
```javascript |
|||
let blockheight; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockheight=502; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getblockhash", |
|||
"params": [ "'$blockheight'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getblockhash $blockheight |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblockhash', [ blockheight ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37" |
|||
``` |
|||
|
|||
Returns block's hash by height. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockheight | Required | height of the block in the blockchain. |
|||
|
|||
|
|||
|
|||
## getblockheader |
|||
|
|||
```javascript |
|||
let blockhash, verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockhash='00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37'; |
|||
verbose=1; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getblockheader", |
|||
"params": [ "'$blockhash'", "'$details'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getblockheader $blockhash $verbose |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getblockheader', [ blockheight, verbose ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"hash": "00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37", |
|||
"confirmations": 1177934, |
|||
"height": 502, |
|||
"version": 1, |
|||
"versionHex": "00000001", |
|||
"merkleroot": "4f7a9087973b891fc86cc59fd9c2cb696f7a813360d3553626dc6c38909f9571", |
|||
"time": 1296746959, |
|||
"mediantime": 1296746728, |
|||
"bits": 486604799, |
|||
"difficulty": 1, |
|||
"chainwork": "000000000000000000000000000000000000000000000000000001f701f701f7", |
|||
"previousblockhash": "00000000c7f50b6dfac8b8a59e11b7e62f07fdef20597089b9c5d64ebfe6d682", |
|||
"nextblockhash": "00000000f797111d0f67d7f08346757948e7c469f14cddbd1c3d0217306bf003" |
|||
} |
|||
``` |
|||
|
|||
Returns block's header by hash. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockheight | Required | height of the block in the blockchain. |
|||
2 | verbose | true | If set to false, it will return hex of the block. |
|||
|
|||
|
|||
|
|||
## getchaintips |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getchaintips" |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getchaintips |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getchaintips'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
Returns chaintips. |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"height": 1159071, |
|||
"hash": "0000000000043bc8896351bf4fbb9fadfa596566e6d88078a2364252346e0d2a", |
|||
"branchlen": 1, |
|||
"status": "valid-headers" |
|||
}, |
|||
{ |
|||
"height": 1158313, |
|||
"hash": "0000000000011e8328cf0382888e07f207e178e967f896794d600e39c962362e", |
|||
"branchlen": 1, |
|||
"status": "valid-headers" |
|||
}, |
|||
... |
|||
] |
|||
``` |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getdifficulty |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getdifficulty" |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getdifficulty |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getdifficulty'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
1048576 |
|||
``` |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
@ -0,0 +1,144 @@ |
|||
# RPC Calls - Chain |
|||
|
|||
## pruneblockchain |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "pruneblockchain", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc pruneblockchain |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('pruneblockchain'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
Prunes the blockchain, it will keep blocks specified in Network Configurations. |
|||
|
|||
### Default Prune Options |
|||
Network | keepBlocks | pruneAfter |
|||
------- | ------- | ------- |
|||
main | 288 | 1000 |
|||
testnet | 10000 | 1000 |
|||
regtest | 10000 | 1000 |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## invalidateblock |
|||
|
|||
```javascript |
|||
let blockhash; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockhash='0000000000000dca8da883af9515dd90443d59139adbda3f9eeac1d18397fec3'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "invalidateblock", |
|||
"params": [ "'$blockhash'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc invalidateblock $blockhash |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('invalidateblock', [ blockhash ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
|
|||
Invalidates the block in the chain. |
|||
It will rewind network to blockhash and invalidate it. |
|||
|
|||
It won't accept that block as valid |
|||
*Invalidation will work while running, restarting node will remove invalid block from list.* |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockhash | Required | Block's hash |
|||
|
|||
|
|||
|
|||
## reconsiderblock |
|||
|
|||
```javascript |
|||
let blockhash; |
|||
``` |
|||
|
|||
```shell--vars |
|||
blockhash='0000000000000dca8da883af9515dd90443d59139adbda3f9eeac1d18397fec3'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "reconsiderblock", |
|||
"params": [ "'$blockhash'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc reconsiderblock $blockhash |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('reconsiderblock', [ blockhash ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
This rpc command will remove block from invalid block set. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | blockhash | Required | Block's hash |
@ -0,0 +1,541 @@ |
|||
## stop |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "method": "stop" }' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc stop |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('stop'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"Stopping." |
|||
``` |
|||
|
|||
Stops the running node. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getinfo", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"version": "v1.0.0-beta.14", |
|||
"protocolversion": 70015, |
|||
"walletversion": 0, |
|||
"balance": 0, |
|||
"blocks": 1178980, |
|||
"timeoffset": 0, |
|||
"connections": 8, |
|||
"proxy": "", |
|||
"difficulty": 1048576, |
|||
"testnet": true, |
|||
"keypoololdest": 0, |
|||
"keypoolsize": 0, |
|||
"unlocked_until": 0, |
|||
"paytxfee": 0.0002, |
|||
"relayfee": 0.00001, |
|||
"errors": "" |
|||
} |
|||
``` |
|||
|
|||
Returns general info |
|||
|
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getmemoryinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getmemoryinfo", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getmemoryinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getmemoryinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"total": 99, |
|||
"jsHeap": 19, |
|||
"jsHeapTotal": 29, |
|||
"nativeHeap": 69, |
|||
"external": 10 |
|||
} |
|||
``` |
|||
|
|||
Returns Memory usage info. |
|||
|
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## setloglevel |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "setloglevel", |
|||
"params": [ "none" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc setloglevel none |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('setloglevel', [ 'none' ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Change Log level of the running node. |
|||
|
|||
Levels are: `NONE`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, `SPAM` |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | level | Required | Level for the logger |
|||
|
|||
|
|||
## validateaddress |
|||
|
|||
```javascript |
|||
let address; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address='n34pHHSqsXJQwq9FXUsrfhmTghrVtN74yo'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "validateaddress", |
|||
"params": [ "'$address'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc validateaddress $address |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('validateaddress', [ address ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"isvalid": true, |
|||
"address": "n34pHHSqsXJQwq9FXUsrfhmTghrVtN74yo", |
|||
"scriptPubKey": "76a914ec61435a3c8f0efee2ffafb8ddb4e1440d2db8d988ac", |
|||
"ismine": false, |
|||
"iswatchonly": false |
|||
} |
|||
``` |
|||
|
|||
Validates address. |
|||
|
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | address | Required | Address to validate |
|||
|
|||
|
|||
|
|||
## createmultisig |
|||
|
|||
```javascript |
|||
let nrequired, pubkey0, pubkey1, pubkey2; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nrequired=2; |
|||
pubkey0='02b3280e779a7c849f9d6460e926097fe4b0f6280fa6fd038ce8e1236a4688c358'; |
|||
pubkey1='021f1dbc575db95a44e016fe6ecf00231109e7799d9b1e007dbe8814017cf0d65c'; |
|||
pubkey2='0315613667e3ebe065c0b8d86ae0443d97de56545bdf38c99a6ee584f300206d9a'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "createmultisig", |
|||
"params": [ "'$nrequired'", [ "'$pubkey0'", "'$pubkey1'", "'$pubkey2'" ] ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc createmultisig $nrequired '[ "'$pubkey0'", "'$pubkey1'", "'$pubkey2'" ]' |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('createmultisig', [ nrequired, [ pubkey0, pubkey1, pubkey2 ] ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"address": "2MzY9R5P1Wfy9aNdqyoH63K1EQZF7APuZ4S", |
|||
"redeemScript": "5221021f1dbc575db95a44e016fe6ecf00231109e7799d9b1e007dbe8814017cf0d65c2102b3280e779a7c849f9d6460e926097fe4b0f6280fa6fd038ce8e1236a4688c358210315613667e3ebe065c0b8d86ae0443d97de56545bdf38c99a6ee584f300206d9a53ae" |
|||
} |
|||
|
|||
``` |
|||
|
|||
create multisig address |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | nrequired | Required | Required number of approvals for spending |
|||
2 | keyArray | Required | Array of public keys |
|||
|
|||
|
|||
|
|||
## createwitnessaddress |
|||
|
|||
```javascript |
|||
let script; |
|||
``` |
|||
|
|||
```shell--vars |
|||
script='5221021f1dbc575db95a44e016fe6ecf00231109e7799d9b1e007dbe8814017cf0d65c2102b3280e779a7c849f9d6460e926097fe4b0f6280fa6fd038ce8e1236a4688c358210315613667e3ebe065c0b8d86ae0443d97de56545bdf38c99a6ee584f300206d9a53ae'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "createwitnessaddress", |
|||
"params": [ "'$script'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc createwitnessaddress $script |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('createwitnessaddress', [ script ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"address": "tb1qlfgqame3n0dt2ldjl2m9qjg6n2vut26jw3ezm25hqx9ez4m9wp5q567kg2", |
|||
"witnessScript": "0020fa500eef319bdab57db2fab650491a9a99c5ab5274722daa97018b9157657068" |
|||
} |
|||
``` |
|||
|
|||
Creates witness address. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | script | Required | Bitcoin script. |
|||
|
|||
|
|||
|
|||
## signmessagewithprivkey |
|||
|
|||
```javascript |
|||
let privkey, message; |
|||
``` |
|||
|
|||
```shell--vars |
|||
privkey='EL4QU6ViZvT4RuCTCivw2uBnvBPSamP5jMtH31gGQLbEEcmNCHVz'; |
|||
message='hello'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "signmessagewithprivkey", |
|||
"params": [ "'$privkey'", "'$message'"] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc signmessagewithprivkey $privkey $message |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('signmessagewithprivkey', [ privkey, message ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"MEQCIAwF9NPMo5KBRsCWTBJ2r69/h7CfDl+RQfxxwAbNp1WJAiAiubiK5rg9MugiU7EHpwbJLc3b356LAedob0ePI40Wmg==" |
|||
``` |
|||
|
|||
|
|||
Signs message with private key. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | privkey | Required | Private key |
|||
1 | message | Required | Message you want to sign. |
|||
|
|||
|
|||
## verifymessage |
|||
|
|||
```javascript |
|||
let address, signature, message; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address='R9LTC6Sp6Zwk71qUrm81sEdsppFNiDM6mF'; |
|||
signature='MEQCIAwF9NPMo5KBRsCWTBJ2r69/h7CfDl+RQfxxwAbNp1WJAiAiubiK5rg9MugiU7EHpwbJLc3b356LAedob0ePI40Wmg=='; |
|||
message='hello'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "verifymessage", |
|||
"params": [ "'$address'", "'$signature'", "'$message'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc verifymessage $address $signature $message |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('verifymessage', [ address, signature, message ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
true |
|||
``` |
|||
|
|||
Verify sign |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | address | Required | Address of the signer |
|||
2 | signature | Required | Signature of signed message |
|||
3 | message | Required | Message that was signed |
|||
|
|||
## setmocktime |
|||
|
|||
```javascript |
|||
let timestamp; |
|||
``` |
|||
|
|||
```shell--vars |
|||
timestamp=1503058155; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "setmocktime", |
|||
"params": [ '$timestamp' ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc setmocktime $timestamp |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('setmocktime', [ timestamp ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
|
|||
Changes network time (This is consensus-critical) |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | timestamp | Required | timestamp to change to |
@ -0,0 +1,651 @@ |
|||
# RPC Calls - Mempool |
|||
|
|||
## getmempoolinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getmempoolinfo" |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getmempoolinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getmempoolinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"size": 20, |
|||
"bytes": 68064, |
|||
"usage": 68064, |
|||
"maxmempool": 100000000, |
|||
"mempoolminfee": 0.00001 |
|||
} |
|||
``` |
|||
|
|||
Returns informations about mempool. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getmempoolancestors |
|||
|
|||
```javascript |
|||
let txhash, verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='939a3b8485b53a718d89e7e4412473b3762fa1d9bbd555fc8b01e73be0ab1881'; |
|||
verbose=1; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getmempoolancestors", |
|||
"params": [ "'$txhash'", "'$verbose'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getmempoolancestors $txhash $verbose |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getmempoolancestors', [ txhash, verbose ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
// verbose=1 |
|||
[ |
|||
{ |
|||
"size": 225, |
|||
"fee": 0.0000454, |
|||
"modifiedfee": 0, |
|||
"time": 1502891340, |
|||
"height": 201, |
|||
"startingpriority": 0, |
|||
"currentpriority": 0, |
|||
"descendantcount": 1, |
|||
"descendantsize": 451, |
|||
"descendantfees": 9080, |
|||
"ancestorcount": 0, |
|||
"ancestorsize": 0, |
|||
"ancestorfees": 0, |
|||
"depends": [] |
|||
} |
|||
] |
|||
``` |
|||
|
|||
```json |
|||
// verbose=0 |
|||
[ |
|||
"56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8" |
|||
] |
|||
``` |
|||
|
|||
returns all in-mempool ancestors for a transaction in the mempool. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txhash | Required | Transaction Hash |
|||
2 | verbose | false | False returns only tx hashs, true - returns dependency tx info |
|||
|
|||
|
|||
|
|||
## getmempooldescendants |
|||
|
|||
```javascript |
|||
let txhash, verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8'; |
|||
verbose=1; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getmempooldescendants", |
|||
"params": [ "'$txhash'", "'$verbose'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getmempooldescendants $txhash $verbose |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getmempooldescendants', [ txhash, verbose ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
// verbose=1 |
|||
[ |
|||
{ |
|||
"size": 226, |
|||
"fee": 0.0000454, |
|||
"modifiedfee": 0, |
|||
"time": 1502891378, |
|||
"height": 201, |
|||
"startingpriority": 0, |
|||
"currentpriority": 0, |
|||
"descendantcount": 0, |
|||
"descendantsize": 226, |
|||
"descendantfees": 4540, |
|||
"ancestorcount": 1, |
|||
"ancestorsize": 0, |
|||
"ancestorfees": 0, |
|||
"depends": [ |
|||
"56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8" |
|||
] |
|||
} |
|||
] |
|||
``` |
|||
|
|||
```json |
|||
// verbose=0 |
|||
[ |
|||
"939a3b8485b53a718d89e7e4412473b3762fa1d9bbd555fc8b01e73be0ab1881" |
|||
] |
|||
``` |
|||
|
|||
returns all in-mempool descendants for a transaction in the mempool. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txhash | Required | Transaction hash |
|||
2 | verbose | false | False returns only tx hashs, true - returns dependency tx info |
|||
|
|||
|
|||
|
|||
## getmempoolentry |
|||
|
|||
```javascript |
|||
let txhash; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='939a3b8485b53a718d89e7e4412473b3762fa1d9bbd555fc8b01e73be0ab1881'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getmempoolentry", |
|||
"params": [ "'$txhash'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getmempoolentry $txhash |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getmempoolentry', [ txhash ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"size": 226, |
|||
"fee": 0.0000454, |
|||
"modifiedfee": 0, |
|||
"time": 1502891378, |
|||
"height": 201, |
|||
"startingpriority": 0, |
|||
"currentpriority": 0, |
|||
"descendantcount": 0, |
|||
"descendantsize": 226, |
|||
"descendantfees": 4540, |
|||
"ancestorcount": 1, |
|||
"ancestorsize": 0, |
|||
"ancestorfees": 0, |
|||
"depends": [ |
|||
"56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8" |
|||
] |
|||
} |
|||
``` |
|||
|
|||
returns mempool transaction info by its hash. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txhash | Required | Transaction Hash |
|||
|
|||
|
|||
|
|||
## getrawmempool |
|||
|
|||
```javascript |
|||
let verbose; |
|||
``` |
|||
|
|||
```shell--vars |
|||
verbose=1; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getrawmempool", |
|||
"params": [ "'$verbose'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getrawmempool $verbose |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getrawmempool', [ verbose ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8": { |
|||
"size": 225, |
|||
"fee": 0.0000454, |
|||
"modifiedfee": 0, |
|||
"time": 1502891340, |
|||
"height": 201, |
|||
"startingpriority": 0, |
|||
"currentpriority": 0, |
|||
"descendantcount": 1, |
|||
"descendantsize": 451, |
|||
"descendantfees": 9080, |
|||
"ancestorcount": 0, |
|||
"ancestorsize": 0, |
|||
"ancestorfees": 0, |
|||
"depends": [] |
|||
}, |
|||
"939a3b8485b53a718d89e7e4412473b3762fa1d9bbd555fc8b01e73be0ab1881": { |
|||
"size": 226, |
|||
"fee": 0.0000454, |
|||
"modifiedfee": 0, |
|||
"time": 1502891378, |
|||
"height": 201, |
|||
"startingpriority": 0, |
|||
"currentpriority": 0, |
|||
"descendantcount": 0, |
|||
"descendantsize": 226, |
|||
"descendantfees": 4540, |
|||
"ancestorcount": 1, |
|||
"ancestorsize": 0, |
|||
"ancestorfees": 0, |
|||
"depends": [ |
|||
"56ab7663c80cb6ffc9f8a4b493d77b2e6f52ae8ff64eefa8899c2065922665c8" |
|||
] |
|||
} |
|||
} |
|||
``` |
|||
|
|||
Returns mempool detailed information (on verbose). |
|||
Or mempool tx list. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | verbose | false | False returns only tx hashs, true - returns full tx info |
|||
|
|||
|
|||
|
|||
## prioritisetransaction |
|||
|
|||
```javascript |
|||
let txhash, priorityDelta, feeDelta; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash=''; |
|||
priorityDelta=1000; |
|||
feeDelta=1000; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "prioritisetransaction", |
|||
"params": [ "'$txhash'", "'$priorityDelta'", "'$feeDelta'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc prioritisetransaction $txhash $priorityDelta $feeDelta |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('prioritisetransaction', [ txhash, priorityDelta, feeDelta ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
true |
|||
``` |
|||
|
|||
Prioritises the transaction. |
|||
|
|||
*Note: changing fee or priority will only trick local miner (using this mempool) |
|||
into accepting Transaction(s) into the block. (even if Priority/Fee doen't qualify)* |
|||
|
|||
|
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txid | Required | Transaction hash |
|||
2 | priority delta | Required | Virtual priority to add/subtract to the entry |
|||
3 | fee delta | Required | Virtual fee to add/subtract to the entry |
|||
|
|||
|
|||
|
|||
## estimatefee |
|||
|
|||
```javascript |
|||
let nblocks; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nblocks=10; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "estimatefee", |
|||
"params": [ "'$nblocks'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc estimatefee $nblocks |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('estimatefee', [ nblocks ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
0.001 |
|||
``` |
|||
|
|||
Estimates fee to be paid for transaction. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | nblocks | 1 | Number of blocks to check for estimation. |
|||
|
|||
|
|||
|
|||
## estimatepriority |
|||
|
|||
```javascript |
|||
let nblocks; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nblocks=10; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "estimatepriority", |
|||
"params": [ "'$nblocks'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc estimatepriority $nblocks |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('estimatepriority', [ nblocks ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
718158904.3501 |
|||
``` |
|||
|
|||
estimates the priority (coin age) that a transaction needs in order to be included within a certain number of blocks as a free high-priority transaction. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | nblocks | 1 | Number of blocks to check for estimation. |
|||
|
|||
|
|||
|
|||
## estimatesmartfee |
|||
|
|||
```javascript |
|||
let nblocks; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nblocks=10; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "estimatesmartfee", |
|||
"params": [ "'$nblocks'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc estimatesmartfee $nblocks |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('estimatesmartfee', [ nblocks ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"fee": 0.001, |
|||
"blocks": 10 |
|||
} |
|||
``` |
|||
|
|||
Estimates smart fee to be paid for transaction. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | nblocks | 1 | Number of blocks to check for estimation. |
|||
|
|||
|
|||
|
|||
## estimatesmartpriority |
|||
|
|||
```javascript |
|||
let nblocks; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nblocks=10; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "estimatesmartpriority", |
|||
"params": [ "'$nblocks'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc estimatesmartpriority $nblocks |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('estimatesmartpriority', [ nblocks ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"priority": 718158904.3501, |
|||
"blocks": 10 |
|||
} |
|||
``` |
|||
|
|||
estimates smart priority (coin age) that a transaction needs in order to be included within a certain number of blocks as a free high-priority transaction. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | nblocks | 1 | Number of blocks to check for estimation. |
|||
|
|||
|
|||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,614 @@ |
|||
# RPC Calls - Network |
|||
|
|||
## getconnectioncount |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getconnectioncount", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getconnectioncount |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getconnectioncount'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
8 |
|||
``` |
|||
|
|||
Returns connection count. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
## ping |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "ping", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc ping |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('ping'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Will send ping request to every connected peer. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getpeerinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getpeerinfo", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getpeerinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getpeerinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"id": 1, |
|||
"addr": "198.51.100.82:18333", |
|||
"addrlocal": "203.0.113.114:60760", |
|||
"services": "0000000d", |
|||
"relaytxes": true, |
|||
"lastsend": 1503257171, |
|||
"lastrecv": 1503257171, |
|||
"bytessent": 1962, |
|||
"bytesrecv": 32499, |
|||
"conntime": 121, |
|||
"timeoffset": -1, |
|||
"pingtime": 0.143, |
|||
"minping": 0.143, |
|||
"version": 70015, |
|||
"subver": "/Satoshi:0.14.1/", |
|||
"inbound": false, |
|||
"startingheight": 1179570, |
|||
"besthash": null, |
|||
"bestheight": -1, |
|||
"banscore": 0, |
|||
"inflight": [], |
|||
"whitelisted": false |
|||
}, |
|||
... |
|||
] |
|||
``` |
|||
|
|||
Returns information about all connected peers. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
|
|||
## addnode |
|||
|
|||
```javascript |
|||
let nodeAddr, cmd; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nodeAddr='198.51.100.82:18333'; |
|||
cmd='add' |
|||
``` |
|||
|
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "addnode", |
|||
"params": [ "'$nodeAddr'", "'$cmd'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc addnode $nodeAddr $cmd |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('addnode', [ nodeAddr, cmd ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Adds or removes peers in Host List. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | addr | Required | IP Address of the Node. |
|||
2 | cmd | Required | Command |
|||
|
|||
### Commands |
|||
Command | Description |
|||
---- | ---- |
|||
add | Adds node to Host List and connects to it |
|||
onetry | Tries to connect to the given node |
|||
remove | Removes node from host list |
|||
|
|||
|
|||
|
|||
## disconnectnode |
|||
|
|||
```javascript |
|||
let nodeAddr; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nodeAddr='198.51.100.82:18333'; |
|||
``` |
|||
|
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "disconnectnode", |
|||
"params": [ "'$nodeAddr'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc disconnectnode $nodeAddr |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('disconnectnode', [ nodeAddr ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Disconnects node. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | addr | Required | IP Address of the Node. |
|||
|
|||
|
|||
|
|||
## getaddednodeinfo |
|||
|
|||
```javascript |
|||
let nodeAddr; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nodeAddr='198.51.100.82:18333'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getaddednodeinfo", |
|||
"params": [ "'$nodeAddr'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getaddednodeinfo $nodeAddr |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getaddednodeinfo', [ nodeAddr ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"addednode": "198.51.100.82:18333", |
|||
"connected": true, |
|||
"addresses": [ |
|||
{ |
|||
"address": "198.51.100.82:18333", |
|||
"connected": "outbound" |
|||
} |
|||
] |
|||
} |
|||
] |
|||
``` |
|||
|
|||
Returns node information from host list. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | addr | Required | IP Address of the Node. |
|||
|
|||
|
|||
|
|||
## getnettotals |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getnettotals", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getnettotals |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getnettotals'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"totalbytesrecv": 370598, |
|||
"totalbytessent": 110058, |
|||
"timemillis": 1503262547279 |
|||
} |
|||
``` |
|||
|
|||
Returns information about used network resources. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getnetworkinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getnetworkinfo", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getnetworkinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getnetworkinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"version": "v1.0.0-beta.14", |
|||
"subversion": "/bcoin:v1.0.0-beta.14/", |
|||
"protocolversion": 70015, |
|||
"localservices": "00000009", |
|||
"localrelay": true, |
|||
"timeoffset": -1, |
|||
"networkactive": true, |
|||
"connections": 8, |
|||
"networks": [], |
|||
"relayfee": 0.00001, |
|||
"incrementalfee": 0, |
|||
"localaddresses": [ |
|||
{ |
|||
"address": "203.0.113.114", |
|||
"port": 18333, |
|||
"score": 3 |
|||
} |
|||
], |
|||
"warnings": "" |
|||
} |
|||
``` |
|||
|
|||
Returns local node's network information |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## setban |
|||
|
|||
```javascript |
|||
let nodeAddr, cmd; |
|||
``` |
|||
|
|||
```shell--vars |
|||
nodeAddr='198.51.100.82:18333'; |
|||
cmd='add' |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "setban", |
|||
"params": [ "'$nodeAddr'", "'$cmd'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc setban $nodeAddr $cmd |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('setban', [ nodeAddr, cmd ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Adds or removes nodes from banlist. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | addr | Required | IP Address of the Node. |
|||
2 | cmd | Required | Command |
|||
|
|||
### Commands |
|||
Command | Description |
|||
---- | ---- |
|||
add | Adds node to ban list, removes from host list, disconnects. |
|||
remove | Removes node from ban list |
|||
|
|||
|
|||
|
|||
## listbanned |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "listbanned", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc listbanned |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('listbanned'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"address": "198.51.100.82:18333", |
|||
"banned_until": 1503349501, |
|||
"ban_created": 1503263101, |
|||
"ban_reason": "" |
|||
}, |
|||
... |
|||
] |
|||
``` |
|||
|
|||
Lists all banned peers. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## clearbanned |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "clearbanned", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc clearbanned |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('clearbanned'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
null |
|||
``` |
|||
|
|||
Removes all banned peers. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
@ -0,0 +1,680 @@ |
|||
# RPC Calls - Transactions |
|||
|
|||
## gettxout |
|||
|
|||
```javascript |
|||
let txhash, index, includemempool; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='28d65fdaf5334ffd29066d7076f056bb112baa4bb0842f6eaa06171c277b4e8c'; |
|||
index=0; |
|||
includemempool=1; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "gettxout", |
|||
"params": [ "'$txhash'", "'$index'", "'$includemempool'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc gettxout $txhash $index $includemempool |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('gettxout', [ txhash, index, includemempool ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"bestblock": "00000000000004f0fbf1b2290e8255bbd468640d747fd9d44a16e77d9e129a55", |
|||
"confirmations": 1, |
|||
"value": 1.01, |
|||
"scriptPubKey": { |
|||
"asm": "OP_HASH160 6a58967510cfd7e04987b245f73dbf62e8d3fdf8 OP_EQUAL", |
|||
"hex": "a9146a58967510cfd7e04987b245f73dbf62e8d3fdf887", |
|||
"type": "SCRIPTHASH", |
|||
"reqSigs": 1, |
|||
"addresses": [ |
|||
"2N2wXjoQbEQTKQuqYdkpHMp7rPpnpumYYqe" |
|||
] |
|||
}, |
|||
"version": 1, |
|||
"coinbase": false |
|||
} |
|||
``` |
|||
|
|||
Get outpoint of the transaction. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txid | Required | Transaction hash |
|||
2 | index | Required | Index of the Outpoint tx. |
|||
3 | includemempool | true | Whether to include mempool transactions. |
|||
|
|||
|
|||
|
|||
## gettxoutsetinfo |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "gettxoutsetinfo", |
|||
"params": [] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc gettxoutsetinfo |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('gettxoutsetinfo'); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"height": 1178729, |
|||
"bestblock": "00000000000004f0fbf1b2290e8255bbd468640d747fd9d44a16e77d9e129a55", |
|||
"transactions": 14827318, |
|||
"txouts": 17644185, |
|||
"bytes_serialized": 0, |
|||
"hash_serialized": 0, |
|||
"total_amount": 20544080.67292757 |
|||
} |
|||
``` |
|||
|
|||
Returns information about UTXO's from Chain. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
None. | |
|||
|
|||
|
|||
|
|||
## getrawtransaction |
|||
|
|||
```javascript |
|||
let txhash, verbose=0; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='28d65fdaf5334ffd29066d7076f056bb112baa4bb0842f6eaa06171c277b4e8c'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "getrawtransaction", |
|||
"params": [ "'$txhash'", "'$verbose'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc getrawtransaction $txhash $verbose |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('getrawtransaction', [ txhash, verbose ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"0100000002500310ff36beb6c3608230534ef995f7751b6f948aeea8d21d5cc9dd5023a2c4010000006b483045022100e7c71d397b687f9f30e6003ceedc4c50436fdb2329b7a8a36c9c6759077969d30220059f24e917260d3e601c77079d03c9e73d04fd85f625eaebfd14a1ff695a72230121020bc134c91f4ff068f3a970616fad577f949406c18849321a2f6d4df96fc56c77feffffffeffed95ded4f227fc6717f224e85e50348ce0198303a5418f157ade42828a1e3000000006b483045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e320121022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8feffffff02402305060000000017a9146a58967510cfd7e04987b245f73dbf62e8d3fdf8871e194f00000000001976a914132b05f47f2b1b56f26a78d3962e3acd0735f12d88ac00000000" |
|||
``` |
|||
|
|||
Returns raw transaction |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txhash | Required | Transaction hash |
|||
2 | verbose | false | Returns json formatted if true |
|||
|
|||
|
|||
|
|||
## decoderawtransaction |
|||
|
|||
```javascript |
|||
let rawtx; |
|||
``` |
|||
|
|||
```shell--vars |
|||
rawtx='0100000002500310ff36beb6c3608230534ef995f7751b6f948aeea8d21d5cc9dd5023a2c4010000006b483045022100e7c71d397b687f9f30e6003ceedc4c50436fdb2329b7a8a36c9c6759077969d30220059f24e917260d3e601c77079d03c9e73d04fd85f625eaebfd14a1ff695a72230121020bc134c91f4ff068f3a970616fad577f949406c18849321a2f6d4df96fc56c77feffffffeffed95ded4f227fc6717f224e85e50348ce0198303a5418f157ade42828a1e3000000006b483045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e320121022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8feffffff02402305060000000017a9146a58967510cfd7e04987b245f73dbf62e8d3fdf8871e194f00000000001976a914132b05f47f2b1b56f26a78d3962e3acd0735f12d88ac00000000'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "decoderawtransaction", |
|||
"params": [ "'$rawtx'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc decoderawtransaction $rawtx |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('decoderawtransaction', [ rawtx ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"txid": "28d65fdaf5334ffd29066d7076f056bb112baa4bb0842f6eaa06171c277b4e8c", |
|||
"hash": "28d65fdaf5334ffd29066d7076f056bb112baa4bb0842f6eaa06171c277b4e8c", |
|||
"size": 372, |
|||
"vsize": 372, |
|||
"version": 1, |
|||
"locktime": 0, |
|||
"vin": [ |
|||
{ |
|||
"txid": "c4a22350ddc95c1dd2a8ee8a946f1b75f795f94e53308260c3b6be36ff100350", |
|||
"scriptSig": { |
|||
"asm": "3045022100e7c71d397b687f9f30e6003ceedc4c50436fdb2329b7a8a36c9c6759077969d30220059f24e917260d3e601c77079d03c9e73d04fd85f625eaebfd14a1ff695a722301 020bc134c91f4ff068f3a970616fad577f949406c18849321a2f6d4df96fc56c77", |
|||
"hex": "483045022100e7c71d397b687f9f30e6003ceedc4c50436fdb2329b7a8a36c9c6759077969d30220059f24e917260d3e601c77079d03c9e73d04fd85f625eaebfd14a1ff695a72230121020bc134c91f4ff068f3a970616fad577f949406c18849321a2f6d4df96fc56c77" |
|||
}, |
|||
"sequence": 4294967294, |
|||
"vout": 1 |
|||
}, |
|||
{ |
|||
"txid": "e3a12828e4ad57f118543a309801ce4803e5854e227f71c67f224fed5dd9feef", |
|||
"scriptSig": { |
|||
"asm": "3045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e3201 022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8", |
|||
"hex": "483045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e320121022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8" |
|||
}, |
|||
"sequence": 4294967294, |
|||
"vout": 0 |
|||
} |
|||
], |
|||
"vout": [ |
|||
{ |
|||
"value": 1.01, |
|||
"n": 0, |
|||
"scriptPubKey": { |
|||
"asm": "OP_HASH160 6a58967510cfd7e04987b245f73dbf62e8d3fdf8 OP_EQUAL", |
|||
"hex": "a9146a58967510cfd7e04987b245f73dbf62e8d3fdf887", |
|||
"type": "SCRIPTHASH", |
|||
"reqSigs": 1, |
|||
"addresses": [ |
|||
"2N2wXjoQbEQTKQuqYdkpHMp7rPpnpumYYqe" |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
"value": 0.05183774, |
|||
"n": 1, |
|||
"scriptPubKey": { |
|||
"asm": "OP_DUP OP_HASH160 132b05f47f2b1b56f26a78d3962e3acd0735f12d OP_EQUALVERIFY OP_CHECKSIG", |
|||
"hex": "76a914132b05f47f2b1b56f26a78d3962e3acd0735f12d88ac", |
|||
"type": "PUBKEYHASH", |
|||
"reqSigs": 1, |
|||
"addresses": [ |
|||
"mhGJg1PJg8hVPX9A6zg4q389YFisSzQW6d" |
|||
] |
|||
} |
|||
} |
|||
], |
|||
"blockhash": null, |
|||
"confirmations": 0, |
|||
"time": 0, |
|||
"blocktime": 0 |
|||
} |
|||
``` |
|||
|
|||
Decodes raw tx and provide chain info. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | rawtx | Required | Raw transaction hex |
|||
|
|||
|
|||
|
|||
## decodescript |
|||
|
|||
```javascript |
|||
let script; |
|||
``` |
|||
|
|||
```shell--vars |
|||
script='483045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e320121022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "decodescript", |
|||
"params": [ "'$script'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc decodescript $script |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('decodescript', [ script ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"asm": "3045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e3201 022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8", |
|||
"type": "NONSTANDARD", |
|||
"reqSigs": 1, |
|||
"addresses": [], |
|||
"p2sh": "2MyVRHsEpec67MkPLGr4NR2bT1ZFuzFGUoB" |
|||
} |
|||
``` |
|||
|
|||
Decodes script |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | script | Required | Script hex |
|||
|
|||
|
|||
## sendrawtransaction |
|||
|
|||
```javascript |
|||
let rawtx; |
|||
``` |
|||
|
|||
```shell--vars |
|||
rawtx='0100000002500310ff36beb6c3608230534ef995f7751b6f948aeea8d21d5cc9dd5023a2c4010000006b483045022100e7c71d397b687f9f30e6003ceedc4c50436fdb2329b7a8a36c9c6759077969d30220059f24e917260d3e601c77079d03c9e73d04fd85f625eaebfd14a1ff695a72230121020bc134c91f4ff068f3a970616fad577f949406c18849321a2f6d4df96fc56c77feffffffeffed95ded4f227fc6717f224e85e50348ce0198303a5418f157ade42828a1e3000000006b483045022100f0bde463404db0983e0f221bfa1b13edf1063a78e869295c9457864b122a622b02207d9d5df76ecac6289784201e9a918acb34510c2d65144bf8e4753a3413024e320121022565ed0ff8f79ecf11e8f33b9fbba5606dbc0618813acd74603f9466e88fb8a8feffffff02402305060000000017a9146a58967510cfd7e04987b245f73dbf62e8d3fdf8871e194f00000000001976a914132b05f47f2b1b56f26a78d3962e3acd0735f12d88ac00000000'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "sendrawtransaction", |
|||
"params": [ "'$rawtx'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc sendrawtransaction $rawtx |
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('sendrawtransaction', [ rawtx ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> |
|||
|
|||
```json |
|||
"28d65fdaf5334ffd29066d7076f056bb112baa4bb0842f6eaa06171c277b4e8c" |
|||
``` |
|||
|
|||
Sends raw transaction without verification |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | rawtx | Required | Raw transaction hex |
|||
|
|||
|
|||
|
|||
## createrawtransaction |
|||
|
|||
```javascript |
|||
let txhash, txindex, amount, address, data; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='d1e1b6a8ff8c4d2ade2113a5dd250637e5f99667d36dcae9b70139516cb7052f'; |
|||
txindex=1; |
|||
amount=1; |
|||
|
|||
address='RStiqGLWA3aSMrWDyJvur4287GQ81AtLh1'; |
|||
data=''; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "createrawtransaction", |
|||
"params": [ |
|||
[{ "txid": "'$txhash'", "vout": "'$txindex'" }], |
|||
{ "'$address'": "'$amount'", "data": "'$data'" } |
|||
] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc createrawtransaction \ |
|||
'[{ "txid": "'$txhash'", "vout": "'$txindex'" }]' \ |
|||
'{ "'$address'": "'$amount'", "data": "'$data'" }' |
|||
|
|||
``` |
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'regtest' |
|||
}); |
|||
|
|||
(async () => { |
|||
const sendTo = { |
|||
data: data |
|||
}; |
|||
|
|||
sendTo[address] = amount; |
|||
|
|||
const res = await rpc.execute('createrawtransaction', [ [{ txid: txhash, vout: txindex }], sendTo]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"01000000012f05b76c513901b7e9ca6dd36796f9e5370625dda51321de2a4d8cffa8b6e1d10100000000ffffffff0200e1f505000000001976a914c1325e8fb60bd71d23532c39b4c9e743a2cc764988ac0000000000000000026a0000000000" |
|||
``` |
|||
|
|||
<aside class="info"> |
|||
Note: Transaction in example doesn't specify change output, |
|||
you can do it by specifying another <code>address: amount</code> pair. |
|||
</aside> |
|||
|
|||
Creates raw, unsigned transaction without any formal verification. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | outpoints | Required | Outpoint list |
|||
1.1 | txid | | Transaction Hash |
|||
1.2 | vout | | Transaction Outpoint Index |
|||
1.3 | sequence | | Sequence number for input |
|||
2 | sendto | Required | List of addresses with amounts that we are sending to. |
|||
2.1 | address | 0 | `address: amount` key pairs |
|||
2.2 | data | nullData | Data output |
|||
3 | locktime | | earliest time a transaction can be added |
|||
|
|||
|
|||
## signrawtransaction |
|||
|
|||
```javascript |
|||
let rawtx, txhash, txindex, scriptPubKey, amount, privkey; |
|||
``` |
|||
|
|||
```shell--vars |
|||
rawtx='01000000012f05b76c513901b7e9ca6dd36796f9e5370625dda51321de2a4d8cffa8b6e1d10100000000ffffffff020000000000000000026a0000e1f505000000001976a914c1325e8fb60bd71d23532c39b4c9e743a2cc764988ac00000000'; |
|||
txhash='d1e1b6a8ff8c4d2ade2113a5dd250637e5f99667d36dcae9b70139516cb7052f'; |
|||
txindex=1; |
|||
scriptPubKey='76a9146efd5e2fda72ae2e37f8fb8cde83fbc8025fc96e88ac'; |
|||
amount=1; |
|||
|
|||
privkey='ET4VkeCoHmtKtoWJKco5PBSaVkqsVwqSbsqhneqN4Uo5yaTMxRmV'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "signrawtransaction", |
|||
"params": [ |
|||
"'$rawtx'", |
|||
[{ |
|||
"txid": "'$txhash'", |
|||
"vout": "'$txindex'", |
|||
"scriptPubKey": "'$scriptPubKey'", |
|||
"amount": "'$amount'" |
|||
}], |
|||
[ "'$privkey'" ] |
|||
] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc signrawtransaction $rawtx \ |
|||
'[{ "txid": "'$txhash'", "vout": "'$txindex'", "scriptPubKey": "'$scriptPubKey'", "amount": "'$amount'" }]' \ |
|||
'[ "'$privkey'" ]' |
|||
``` |
|||
|
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'regtest' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('signrawtransaction', [ rawtx, |
|||
[{ |
|||
txid: txhash, |
|||
vout: txindex, |
|||
scriptPubKey: scriptPubKey, |
|||
amount: amount |
|||
}], |
|||
[ privkey ] |
|||
]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
{ |
|||
"hex": "01000000012f05b76c513901b7e9ca6dd36796f9e5370625dda51321de2a4d8cffa8b6e1d1010000006b48304502210094252b4db106def63264668717c5ad66e2804c5e1b390c6240e82515fb0c12690220708430b14ceb0a15308e665de21cb3eb9e6cd9e4571e110fbfddf65ef702cd990121035ef2bf6d09a343c4c0be6fb5b489b217c00f477a9878b60ca3ceca4c2b052c3cffffffff020000000000000000026a0000e1f505000000001976a914c1325e8fb60bd71d23532c39b4c9e743a2cc764988ac00000000", |
|||
"complete": true |
|||
} |
|||
``` |
|||
|
|||
Signs raw transaction |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | rawtx | Required | raw tx |
|||
2 | inputs | Required | Coins you're going to spend |
|||
2.1 | txid | | Transaction Hash |
|||
2.2 | vout | | Transaction Outpoint Index |
|||
2.3 | scriptPubKey | | script with pubkey you are going to sign |
|||
2.4 | redeemScript | | redeemScript if tx is P2SH |
|||
3 | privkeylist | | List of private keys |
|||
4 | sighashtype | | Type of signature hash |
|||
|
|||
|
|||
|
|||
## gettxoutproof |
|||
|
|||
```javascript |
|||
let txhash; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='c75f8c12c6d0d1a16d7361b724898968c71de0335993ee589f82fda8ac482bfc'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "gettxoutproof", |
|||
"params": [ "'$txhash'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc gettxoutproof $txhash |
|||
``` |
|||
|
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('gettxoutproof', [ txhash ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
"000000208c13da491196839dd019c4ae0564f351502a4951e11b4302454b020000000000f1788fd057d657150b12e5638c7348fb55fdcda4ff4ddb1d1503de3576de6a4cbe22db58f0ec091b918981c50200000001f1788fd057d657150b12e5638c7348fb55fdcda4ff4ddb1d1503de3576de6a4c0100" |
|||
``` |
|||
|
|||
Checks if transactions are within block. |
|||
Returns raw block. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | txidlist | Required | array of transaction hashes |
|||
2 | blockhash | Based on TX | Block hash |
|||
|
|||
|
|||
## verifytxoutproof |
|||
|
|||
```javascript |
|||
let proof; |
|||
``` |
|||
|
|||
```shell--vars |
|||
proof='000000208c13da491196839dd019c4ae0564f351502a4951e11b4302454b020000000000f1788fd057d657150b12e5638c7348fb55fdcda4ff4ddb1d1503de3576de6a4cbe22db58f0ec091b918981c50200000001f1788fd057d657150b12e5638c7348fb55fdcda4ff4ddb1d1503de3576de6a4c0100'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/ \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ |
|||
"method": "verifytxoutproof", |
|||
"params": [ "'$proof'" ] |
|||
}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rpc verifytxoutproof $proof |
|||
``` |
|||
|
|||
|
|||
```javascript |
|||
const rpc = new bcoin.http.RPCClient({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
const res = await rpc.execute('verifytxoutproof', [ proof ]); |
|||
|
|||
console.log(res); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON "result" like this: |
|||
|
|||
```json |
|||
[] |
|||
``` |
|||
|
|||
Checks the proof for transaction inclusion. |
|||
|
|||
### Params |
|||
N. | Name | Default | Description |
|||
--------- | --------- | --------- | ----------- |
|||
1 | proof | Required | Proof of transaction inclusion. |
@ -0,0 +1,336 @@ |
|||
# Transaction |
|||
Getting transaction information via APi. |
|||
|
|||
<aside class="info"> |
|||
You need to enable <code>index-tx</code> and <code>index-address</code> in order |
|||
to lookup transactions by transaction hashes and addresses, respectively. |
|||
</aside> |
|||
|
|||
## Get tx by txhash |
|||
|
|||
```javascript |
|||
let txhash; |
|||
``` |
|||
|
|||
```shell--vars |
|||
txhash='86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/tx/$txhash |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli tx $txhash |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const tx = await client.getTX(txhash); |
|||
|
|||
console.log(tx); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
{ |
|||
"hash": "86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9", |
|||
"witnessHash": "86150a141ebe5903a5d31e701698a01d598b81f099ea7577dad73033eab02ef9", |
|||
"fee": 50000, |
|||
"rate": 220264, |
|||
"mtime": 1501093478, |
|||
"height": 502, |
|||
"block": "00000000e0290b7c66227c7499692aac5437860ee912424bf8eea3a3883a4e37", |
|||
"time": 1296746959, |
|||
"index": 8, |
|||
"version": 1, |
|||
"flag": 1, |
|||
"inputs": [ |
|||
{ |
|||
"prevout": { |
|||
"hash": "0173a5d24d393127d5e6fc043ff1a00dafc6a2777143cb98a803a0b6e8cd02c7", |
|||
"index": 0 |
|||
}, |
|||
"script": "493046022100be75ae6dbf9eab7656562136511501c83918ca28c5f96565ca1960b3dbb581b6022100d15692af456e8721fddeeb0d6df5d8a147afd8a3b2a39bbceae9b1bdfd53ade20121038e297cf2cf71c16592c36ca48f5b2a5bbb73e776e772079f4c695b12eec1a509", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"coin": { |
|||
"version": 1, |
|||
"height": 502, |
|||
"value": 4824247882, |
|||
"script": "76a914bc7aad9746a0bc03ed9715f13c94e554df90b84688ac", |
|||
"address": "mxhYHwYZdYh1AkLsUbEmU9ZGdvLfoNRdD6", |
|||
"coinbase": false |
|||
} |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"value": 4823922491, |
|||
"script": "76a914682215dfa6912d88f55a1853414d516122fcc66988ac", |
|||
"address": "mq1ZQJW1qPeNPNL83mpAWfNFPW9qwGDR2K" |
|||
}, |
|||
{ |
|||
"value": 275391, |
|||
"script": "76a914edb1dfaf6e0b39449da811275386edf2eb54baba88ac", |
|||
"address": "n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr" |
|||
} |
|||
], |
|||
"locktime": 0 |
|||
} |
|||
``` |
|||
|
|||
### HTTP Request |
|||
`GET /tx/:txhash` |
|||
|
|||
### URL Parameters |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
:txhash | Hash of tx. |
|||
|
|||
|
|||
## Get tx by address |
|||
```javascript |
|||
let address; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address='n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/tx/address/$address |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli tx $address |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const txs = await client.getTXByAddress(address); |
|||
|
|||
console.log(txs); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
[ |
|||
... |
|||
{ |
|||
"hash": "8351d991c5dfb49d534fcd28f56bb2d5b0d5f31f5c9e2e0711b5f86312a5abfe", |
|||
"witnessHash": "8351d991c5dfb49d534fcd28f56bb2d5b0d5f31f5c9e2e0711b5f86312a5abfe", |
|||
"fee": 50000, |
|||
"rate": 129198, |
|||
"mtime": 1501093478, |
|||
"height": 467, |
|||
"block": "00000000057c13f1fa6b30c6ec32284875781e31474a532e96739523d926a9e2", |
|||
"time": 1296743253, |
|||
"index": 20, |
|||
"version": 1, |
|||
"flag": 1, |
|||
"inputs": [ |
|||
{ |
|||
"prevout": { |
|||
"hash": "d4d30e49228051bffe1317a013c06ae53f5325302a03cdcacb3312d0998f512a", |
|||
"index": 1 |
|||
}, |
|||
"script": "47304402201c29f13e8d817f2c2d1ea8b89d1d603677b86d0b4658f5d836bb16c56dc5dc3e02203e815b7ef739ba95c7bbbfdd63f38baa0806ad235f73c7df2492271e0b14ea43012103d50917ce22f377797a28c5e17e33000ea7d7d149d98b942d83f25ef2a223a8aa", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"coin": { |
|||
"version": 1, |
|||
"height": 464, |
|||
"value": 457110, |
|||
"script": "76a914583d5f973c850ec26f8efa39dabf8fbe0fcbb59c88ac", |
|||
"address": "moZXHEWiTwWyy1HSwvNANn9CKoCocPzDwm", |
|||
"coinbase": false |
|||
} |
|||
}, |
|||
{ |
|||
"prevout": { |
|||
"hash": "3d708378adc61ad2b6d623bfbb89df92e3c88f6c85f6e132796d5abefae8c587", |
|||
"index": 1 |
|||
}, |
|||
"script": "0d17a6a8512d174b6b679c375091483045022100a3d133ccd4353c6dbcd9dc035c059b9b45f3c044644613e2311b8290bd02a3fb022026ae0af0adaea2fad2bc76d40d77fde3628031ee73c8e0e36343d5585e9d93f50121029f15918cd48f9e5cecfc1fccf1efc0c518110a6d6258cf14d0ee49a0fd88a535", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"coin": { |
|||
"version": 1, |
|||
"height": 466, |
|||
"value": 966270, |
|||
"script": "76a914edb1dfaf6e0b39449da811275386edf2eb54baba88ac", |
|||
"address": "n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr", |
|||
"coinbase": false |
|||
} |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"value": 1021229, |
|||
"script": "76a91419eb536dc042d76454bea8dbec5ddc384e783e5a88ac", |
|||
"address": "mht16aZhnsHivv3cDGuzgHGvoLFy8rNkg8" |
|||
}, |
|||
{ |
|||
"value": 352151, |
|||
"script": "76a914342e5d1f2eb9c6e99fda90c85ca05aa36616644c88ac", |
|||
"address": "mkGrySSnxcqRbtPCisApj3zXCQVmUUWbf1" |
|||
} |
|||
], |
|||
"locktime": 0 |
|||
} |
|||
] |
|||
``` |
|||
|
|||
Returns transaction objects array by address |
|||
|
|||
### HTTP Request |
|||
`GET /tx/address/:address` |
|||
|
|||
### URL Parameters |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
:address | Bitcoin address. |
|||
|
|||
## Get tx by addresses |
|||
```javascript |
|||
let address0, address1; |
|||
``` |
|||
|
|||
```shell--vars |
|||
address0='n3BmXQPa1dKi3zEyCdCGNHTuE5GLdmw1Tr'; |
|||
address1='mwLHWwWPDwtCBZA7Ltg9QSzKK5icdCU5rb'; |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/tx/address \ |
|||
-H 'Content-Type: application/json' \ |
|||
-X POST \ |
|||
--data '{ "addresses":[ "'$address0'", "'$address1'" ]}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
No CLI Option. |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet' |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.open(); |
|||
|
|||
const txs = await client.getTXByAddress([address0, address1]); |
|||
|
|||
console.log(txs); |
|||
|
|||
await client.close(); |
|||
})().catch((err) => { |
|||
console.error(err.stack); |
|||
}); |
|||
``` |
|||
|
|||
> The above command returns JSON structured like this: |
|||
|
|||
```json |
|||
[ |
|||
... |
|||
{ |
|||
"hash": "4692772a73ea834c836915089acf97f2c790380a2b8fd32f82729da72545d8c5", |
|||
"witnessHash": "4692772a73ea834c836915089acf97f2c790380a2b8fd32f82729da72545d8c5", |
|||
"fee": 50000, |
|||
"rate": 134048, |
|||
"mtime": 1501093478, |
|||
"height": 500, |
|||
"block": "00000000a2424460c992803ed44cfe0c0333e91af04fde9a6a97b468bf1b5f70", |
|||
"time": 1296746771, |
|||
"index": 3, |
|||
"version": 1, |
|||
"flag": 1, |
|||
"inputs": [ |
|||
{ |
|||
"prevout": { |
|||
"hash": "cff00582fa957178139b0db60228fc9b252adc01ec6b11c3e16f708802c12d3f", |
|||
"index": 0 |
|||
}, |
|||
"script": "48304502203ef5c34af08cd2865820757844ac079e081e7b41bf427ac896f41ab12a9f9857022100bd0914548145648ec538c088640228baaa983a7c78fbf49526c5c30358fe0f54012103420f2cb862c7a77d7b2376660573eb6976f01f59222892dd16326ee7ef37fc5b", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"coin": { |
|||
"version": 1, |
|||
"height": 499, |
|||
"value": 346342, |
|||
"script": "76a914f93f789537ba00a23e7e84dcf145dae36f50ea8088ac", |
|||
"address": "n4Eras4wT4kRjX34zP96nCiHqietgeKnTn", |
|||
"coinbase": false |
|||
} |
|||
}, |
|||
{ |
|||
"prevout": { |
|||
"hash": "39661409f6bc4d9e08e413e01f867fe276e12e83dae89ee351df17757ca64b3f", |
|||
"index": 0 |
|||
}, |
|||
"script": "47304402201468bcfff3b1d8bdd0ba5fd94692c4dc7766411bdafe8d65b6e7a5be8f7efa8602207cdcbe3a107db271f24d7d8ac83a887ef4a1b72c910cc9ea5627b4cf37e87bcf0121025f9a9951e2d2a3037c1af09d9789b84a5776c504cd5b59bccd469124eb59835f", |
|||
"witness": "00", |
|||
"sequence": 4294967295, |
|||
"coin": { |
|||
"version": 1, |
|||
"height": 499, |
|||
"value": 1024528, |
|||
"script": "76a914c4a22b009b02fe8488c5543f0873e062712b7f6888ac", |
|||
"address": "mySf1HGynwyAuNyYrapRnwM83k3svzWTgD", |
|||
"coinbase": false |
|||
} |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"value": 1095497, |
|||
"script": "76a914ad7d7b9ac5260ad13fa55e06143283f5b36495f788ac", |
|||
"address": "mwLHWwWPDwtCBZA7Ltg9QSzKK5icdCU5rb" |
|||
}, |
|||
{ |
|||
"value": 225373, |
|||
"script": "76a914bc0f9f5fc9dc55323d52a9e354b5fb67cecd389788ac", |
|||
"address": "mxfL3bJohxaoBkKNtUF8xSU1DVKzbiChnZ" |
|||
} |
|||
], |
|||
"locktime": 0 |
|||
} |
|||
] |
|||
``` |
|||
|
|||
Returns transaction objects array by addresses |
|||
|
|||
### HTTP Request |
|||
`POST /tx/address` |
|||
|
|||
### POST Parameters (JSON) |
|||
Parameter | Description |
|||
--------- | ----------- |
|||
addresses | array of bitcoin addresses |
File diff suppressed because it is too large
@ -0,0 +1,231 @@ |
|||
# Wallet Accounts |
|||
## Account Object |
|||
> An account object looks like this: |
|||
|
|||
```json |
|||
{ |
|||
"wid": 1, |
|||
"id": "test", |
|||
"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": [] |
|||
} |
|||
|
|||
``` |
|||
Represents a BIP44 Account belonging to a Wallet. |
|||
Note that this object does not enforce locks. Any method that does a write is internal API only and will lead to race conditions if used elsewhere. |
|||
|
|||
From the [BIP44 Specification](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki): |
|||
|
|||
<p> |
|||
<code> |
|||
This level splits the key space into independent user identities, so the wallet never mixes the coins across different accounts. |
|||
</code> |
|||
</p> |
|||
<p> |
|||
<code> |
|||
Users can use these accounts to organize the funds in the same fashion as bank accounts; for donation purposes (where all addresses are considered public), for saving purposes, for common expenses etc. |
|||
</code> |
|||
</p> |
|||
<p> |
|||
<code> |
|||
Accounts are numbered from index 0 in sequentially increasing manner. This number is used as child index in BIP32 derivation. |
|||
</code> |
|||
</p> |
|||
<p> |
|||
<code> |
|||
Hardened derivation is used at this level. |
|||
</code> |
|||
</p> |
|||
|
|||
## Get Wallet Account List |
|||
|
|||
```shell--vars |
|||
id='test' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet account list --id=$id |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client(); |
|||
(async () => { |
|||
const accountInfo = await client.getAccounts(id); |
|||
console.log(accountInfo); |
|||
})(); |
|||
``` |
|||
|
|||
> Sample response: |
|||
|
|||
```json |
|||
[ |
|||
"default" |
|||
] |
|||
``` |
|||
|
|||
List all account names (array indices map directly to bip44 account indices) associated with a specific wallet id. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/account` |
|||
|
|||
|
|||
Parameters | Description |
|||
---------- | ----------- |
|||
id <br> _string_ | id of wallet you would like to retrieve the account list for |
|||
|
|||
<aside class="notice"> |
|||
Note that command defaults to primary (default) wallet if no wallet id is passed |
|||
</aside> |
|||
|
|||
## Get Account Information |
|||
```javascript |
|||
let id, account; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id='test' |
|||
account='default' |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/account/$account |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet --id=$id account get $account |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client(); |
|||
(async () => { |
|||
const accountInfo = await client.getAccount(id, account); |
|||
console.log(accountInfo); |
|||
})(); |
|||
``` |
|||
|
|||
> Sample response: |
|||
|
|||
```json |
|||
{ |
|||
"wid": 1, |
|||
"id": "test", |
|||
"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 account info. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/account/:account` |
|||
|
|||
Parameters | Description |
|||
---------- | ----------- |
|||
id <br> _string_ | id of wallet you would like to query |
|||
account <br> _string_ | id of account you would to retrieve information for |
|||
|
|||
## Create new wallet account |
|||
|
|||
```javascript |
|||
let id, name, type; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id='test' |
|||
name='menace' |
|||
type='multisig' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet --id=$id account create $name --type=$type |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/account/$name \ |
|||
-X PUT |
|||
--data '{"type": "'$type"}' |
|||
``` |
|||
|
|||
```javascript |
|||
const httpWallet = new bcoin.http.Wallet({ id: id }); |
|||
const options = {type: type} |
|||
|
|||
(async () => { |
|||
const account = await httpWallet.createAccount(name, options); |
|||
console.log(account); |
|||
})(); |
|||
``` |
|||
|
|||
> Sample response: |
|||
|
|||
```json |
|||
{ |
|||
"wid": 1, |
|||
"id": "test", |
|||
"name": "menace", |
|||
"initialized": true, |
|||
"witness": false, |
|||
"watchOnly": false, |
|||
"type": "multisig", |
|||
"m": 1, |
|||
"n": 1, |
|||
"accountIndex": 1, |
|||
"receiveDepth": 1, |
|||
"changeDepth": 1, |
|||
"nestedDepth": 0, |
|||
"lookahead": 10, |
|||
"receiveAddress": "mg7b3H3ZCHx3fwvUf8gaRHwcgsL7WdJQXv", |
|||
"nestedAddress": null, |
|||
"changeAddress": "mkYtQFpxDcqutMJtyzKNFPnn97zhft56wH", |
|||
"accountKey": "tpubDC5u44zLNUVo55dtQsJRsbQgeNfrp8ctxVEdDqDQtR7ES9XG5h1SGhkv2HCuKA2RZysaFzkuy5bgxF9egvG5BJgapWwbYMU4BJ1SeSj916G", |
|||
"keys": [] |
|||
} |
|||
``` |
|||
|
|||
Create account with specified account name. |
|||
|
|||
### HTTP Request |
|||
|
|||
`PUT /wallet/:id/account/:name` |
|||
|
|||
### Options object |
|||
Parameter | Description |
|||
--------- | ----------------- |
|||
name <br> _string_ | name to give the account. Option can be `account` or `name` |
|||
witness <br> _bool_ | whether or not to act as segregated witness wallet account |
|||
watchOnly <br> _bool_ | whether or not to make watch only account. Watch only accounts can't accept private keys for import (or sign transactions) |
|||
type <br> _string_ | what type of wallet to make it ('multisig', 'pubkeyhash') |
|||
m <br> _int_ | for multisig accounts, what to make `m` in m-of-n |
|||
n <br> _int_ | for multisig accounts, what to make the `n` in m-of-n |
@ -0,0 +1,162 @@ |
|||
# Wallet Admin |
|||
The _admin namespace exists to differentiate administrative level tasks on the wallet API that you probably don't want to expose to individual wallets. |
|||
|
|||
`/wallet/_admin/[TARGET_ACTION]` |
|||
|
|||
<aside class="notice"> |
|||
Replace `[TARGET_ACTION]` with one of the available actions listed below |
|||
</aside> |
|||
|
|||
## Wallet Rescan |
|||
```javascript |
|||
let height; |
|||
``` |
|||
|
|||
```shell--vars |
|||
height = 50000 |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/_admin/rescan \ |
|||
-X POST \ |
|||
--data '{"height": '$height'}' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli rescan $height |
|||
``` |
|||
|
|||
```javascript |
|||
const height = 50000; |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet', |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.rescan(height); |
|||
})(); |
|||
|
|||
``` |
|||
|
|||
> Response Body: |
|||
|
|||
```json |
|||
{"success": true} |
|||
``` |
|||
|
|||
Initiates a blockchain rescan for the walletdb. Wallets will be rolled back to the specified height (transactions above this height will be unconfirmed). |
|||
|
|||
### Example HTTP Request |
|||
`POST /wallet/_admin/rescan?height=50000` |
|||
|
|||
|
|||
## Wallet Resend |
|||
```shell--curl |
|||
curl $url/wallet/_admin/resend \ |
|||
-X POST |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli resend |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet', |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.resend(); |
|||
})(); |
|||
|
|||
``` |
|||
|
|||
> Response Body: |
|||
|
|||
```json |
|||
{"success": true} |
|||
``` |
|||
|
|||
Rebroadcast all pending transactions in all wallets. |
|||
|
|||
### HTTP Request |
|||
|
|||
`POST /wallet/_admin/resend` |
|||
|
|||
##Wallet Backup |
|||
```javascript |
|||
let path; |
|||
``` |
|||
|
|||
```shell--vars |
|||
path='/path/to/new/backup' |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/_admin/backup?path=/home/user/walletdb-backup.ldb \ |
|||
-X POST \ |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli backup $path |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet', |
|||
}); |
|||
|
|||
(async () => { |
|||
await client.backup(path); |
|||
})(); |
|||
|
|||
``` |
|||
|
|||
> Response Body: |
|||
|
|||
```json |
|||
{"success": true} |
|||
``` |
|||
|
|||
Safely backup the wallet database to specified path (creates a clone of the database). |
|||
|
|||
### HTTP Request |
|||
|
|||
`POST /wallet/_admin/backup?path=/home/user/walletdb-backup.ldb` |
|||
|
|||
## List all Wallets |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/_admin/wallets |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallets |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
network: 'testnet', |
|||
}); |
|||
|
|||
(async () => { |
|||
const wallets = await client.getWallets(); |
|||
console.log(wallets) |
|||
})(); |
|||
|
|||
``` |
|||
|
|||
> Sample Response Body: |
|||
|
|||
```json |
|||
[ |
|||
"primary", |
|||
"test" |
|||
] |
|||
``` |
|||
|
|||
List all wallet IDs. Returns an array of strings. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/_admin/wallets` |
@ -0,0 +1,309 @@ |
|||
# Wallet Transactions |
|||
|
|||
## Get Wallet TX Details |
|||
|
|||
```javascript |
|||
let id, hash |
|||
``` |
|||
|
|||
```shell--vars |
|||
id="foo" |
|||
hash="18d2cf5683d7befe06941f59b7fb4ca0e915dcb9c6aece4ce8966a29e7c576fe" |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet --id=$id tx $hash |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/tx/$hash |
|||
``` |
|||
|
|||
```javascript |
|||
const httpWallet = new bcoin.http.Wallet({ id: id }); |
|||
|
|||
(async () => { |
|||
const response = await httpWallet.getTX(hash); |
|||
console.log(response); |
|||
})(); |
|||
``` |
|||
> Sample Response |
|||
|
|||
```json |
|||
{ |
|||
"wid": 1, |
|||
"id": "foo", |
|||
"hash": "18d2cf5683d7befe06941f59b7fb4ca0e915dcb9c6aece4ce8966a29e7c576fe", |
|||
"height": -1, |
|||
"block": null, |
|||
"time": 0, |
|||
"mtime": 1507077109, |
|||
"date": "2017-10-04T00:31:49Z", |
|||
"size": 225, |
|||
"virtualSize": 225, |
|||
"fee": 4540, |
|||
"rate": 20177, |
|||
"confirmations": 0, |
|||
"inputs": |
|||
[ { value: 5000009080, |
|||
address: "SdCEuxkbdMygcKtL36x2CT8p1vhz56SsbG", |
|||
path: [Object] } ], |
|||
"outputs": |
|||
[ { value: 100000000, |
|||
address: "SP7K3cSLH66zDisioqPrTC3QSRwP9GPENB", |
|||
path: null }, |
|||
{ value: 4900004540, |
|||
address: "SSzzdLbBeWBwNTUpbGdD9gBk6Wzk34sT7J", |
|||
path: [Object] } ], |
|||
"tx": "010000000148ae6682231f381845f98049c871e9b6bf0a9a7f5c5270354f71079262577977000000006a47304402203359117c409d292700fbacc03e4b540066a6b8ca763f1dd578e8262fe5e74c1b02206c91f816755469cd4a6b110941b51f29e251b86afe246456cf17823ef4fc7f5301210299c1a1049d546a720dd614034ce2802a3f64d64c37b729ae184825f71d0a037affffffff0200e1f505000000001976a91413eab6745a3fcbcf8b4448c130ff8bc37db6e91b88acbc221024010000001976a9143e9958577401fe8d75ed6f162cc6832fcb26094188ac00000000" |
|||
} |
|||
``` |
|||
Get wallet transaction details. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/tx/:hash` |
|||
|
|||
### Request Parameters |
|||
Parameter | Description |
|||
--------- | -------------- |
|||
id <br> _string_ | id of wallet that handled the transaction |
|||
hash <br> _string_ | hash of the transaction you're trying to retrieve |
|||
|
|||
## Delete Transaction |
|||
```javascript |
|||
let id, hash, passphrase; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id="foo" |
|||
hash="2a22606ee555d2c26ec979f0c45cd2dc18c7177056189cb345989749fd58786" |
|||
passphrase="bar" |
|||
``` |
|||
|
|||
```shell--cli |
|||
# Not available in CLI |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/tx/$hash \ |
|||
-X DELETE \ |
|||
--data '{"passphrase": "'$passphrase'"}' |
|||
``` |
|||
|
|||
```javascript |
|||
// Not available in javascript wallet client. |
|||
``` |
|||
|
|||
Abandon single pending transaction. Confirmed transactions will throw an error. |
|||
`"TX not eligible"` |
|||
|
|||
### HTTP Request |
|||
|
|||
`DEL /wallet/:id/tx/:hash` |
|||
|
|||
Paramters | Description |
|||
----------| -------------------- |
|||
id <br> _string_ | id of wallet where the transaction is that you want to remove |
|||
hash <br> _string_ | hash of transaction you would like to remove. |
|||
|
|||
## Get Wallet TX History |
|||
|
|||
```javascript |
|||
let id; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id='foo' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet --id=$id history |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/tx/history |
|||
``` |
|||
|
|||
```javascript |
|||
const httpWallet = new bcoin.http.Wallet({ id: id }); |
|||
const account = 'default'; |
|||
|
|||
(async () => { |
|||
const response = await httpWallet.getHistory(account); |
|||
console.log(response); |
|||
})(); |
|||
``` |
|||
> Sample Response |
|||
|
|||
```json |
|||
[ |
|||
{ |
|||
"wid": 1, |
|||
"id": "primary", |
|||
"hash": "f5968051ce275d89b7a6b797eb6e6b081243ecf027872fc6949fae443e21b858", |
|||
"height": -1, |
|||
"block": null, |
|||
"time": 0, |
|||
"mtime": 1503690544, |
|||
"date": "2017-08-25T19:49:04Z", |
|||
"size": 226, |
|||
"virtualSize": 226, |
|||
"fee": 0, |
|||
"rate": 0, |
|||
"confirmations": 0, |
|||
"inputs": [ |
|||
{ |
|||
"value": 0, |
|||
"address": "mp2w1u4oqZnHDd1zDeAvCTX9B3SaFsUFQx", |
|||
"path": null |
|||
} |
|||
], |
|||
"outputs": [ |
|||
{ |
|||
"value": 100000, |
|||
"address": "myCkrhQbJwqM8wKi9YuhyTjN3pukNuWxZ9", |
|||
"path": { |
|||
"name": "default", |
|||
"account": 0, |
|||
"change": false, |
|||
"derivation": "m/0'/0/3" |
|||
} |
|||
}, |
|||
{ |
|||
"value": 29790920, |
|||
"address": "mqNm1rSYVqD23Aj6fkupApuSok9DNZAeBk", |
|||
"path": null |
|||
} |
|||
], |
|||
"tx": "0100000001ef8a38cc946c57634c2db05fc298bf94f5c88829c5a6e2b0610fcc7b38a9264f010000006b483045022100e98db5ddb92686fe77bb44f86ce8bf6ff693c1a1fb2fb434c6eeed7cf5e7bed4022053dca3980a902ece82fb8e9e5204c26946893388e4663dbb71e78946f49dd0f90121024c4abc2a3683891b35c04e6d40a07ee78e7d86ad9d7a14265fe214fe84513676ffffffff02a0860100000000001976a914c2013ac1a5f6a9ae91f66e71bbfae4cc762c2ca988acc892c601000000001976a9146c2483bf52052e1125fc75dd77dad06d65b70a8288ac00000000" |
|||
}, |
|||
... |
|||
] |
|||
``` |
|||
|
|||
Get wallet TX history. Returns array of tx details. |
|||
|
|||
### HTTP Request |
|||
`GET /wallet/:id/tx/history` |
|||
|
|||
### Request Parameters |
|||
Paramter | Description |
|||
-------- | ------------------------- |
|||
id <br> _string_ | id of wallet to get history of |
|||
|
|||
## Get Pending Transactions |
|||
|
|||
```javascript |
|||
let id; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id='foo' |
|||
``` |
|||
|
|||
```shell--cli |
|||
bcoin cli wallet --id=$id pending |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/tx/unconfirmed |
|||
``` |
|||
|
|||
```javascript |
|||
const httpWallet = new bcoin.http.Wallet({ id: id }); |
|||
|
|||
(async () => { |
|||
const response = await httpWallet.getPending(account); |
|||
console.log(response); |
|||
})(); |
|||
``` |
|||
|
|||
Get pending wallet transactions. Returns array of tx details. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/tx/unconfirmed` |
|||
|
|||
### Request Parameters |
|||
Paramter | Description |
|||
-------- | ------------------------- |
|||
id <br> _string_ | id of wallet to get pending/unconfirmed txs |
|||
|
|||
|
|||
## Get Range of Transactions |
|||
```javascript |
|||
let id, account, start, end; |
|||
``` |
|||
|
|||
```shell--vars |
|||
id="foo" |
|||
account="foo" |
|||
start="1506909119" |
|||
end="1506909154" |
|||
``` |
|||
|
|||
```shell--cli |
|||
# range not available in CLI |
|||
``` |
|||
|
|||
```shell--curl |
|||
curl $url/wallet/$id/tx/range?start=$start |
|||
``` |
|||
|
|||
```javascript |
|||
const httpWallet = new bcoin.http.Wallet({ id: id }); |
|||
|
|||
(async () => { |
|||
const response = await httpWallet.getRange(account, {start: start, end: end}); |
|||
console.log(response); |
|||
})(); |
|||
``` |
|||
> Sample Response |
|||
|
|||
```json |
|||
[ |
|||
{ "wid": 1, |
|||
"id": "primary", |
|||
"hash": "80ac63671e7b8635d10d372c4c3bed5615624d9fa28dfd747abf440417d70983", |
|||
"height": -1, |
|||
"block": null, |
|||
"time": 0, |
|||
"mtime": 1506909119, |
|||
"date": "2017-10-02T01:51:59Z", |
|||
"size": 200, |
|||
"virtualSize": 173, |
|||
"fee": 0, |
|||
"rate": 0, |
|||
"confirmations": 0, |
|||
"inputs": [ [Object] ], |
|||
"outputs": [ [Object], [Object] ], |
|||
"tx": "010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff20028d010e6d696e65642062792062636f696e045460ad97080000000000000000ffffffff02bc03062a010000001976a914d7ee508e06ece23679ba9ee0a770561ae2ed595688ac0000000000000000266a24aa21a9ed5772988727e8641cf3c7d2bf5a7fee9a5d0e827de0b6bed5658eee8f0821b5200120000000000000000000000000000000000000000000000000000000000000000000000000" |
|||
}, |
|||
... |
|||
] |
|||
``` |
|||
Get range of wallet transactions by timestamp. Returns array of tx details. |
|||
|
|||
<aside class="notice"> |
|||
Note that there are other options documented that `getRange` accepts in the options body, `limit` and `reverse`. At the time of writing however they do not have any effect. |
|||
</aside> |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/tx/range` |
|||
|
|||
### Body Parameters |
|||
Paramter | Description |
|||
-------- | ------------------------- |
|||
account <br>_string_ | account to get the tx history from |
|||
start <br> _int_ | start time to get range from |
|||
end <br> _int_ | end time to get range from |
|||
|
|||
<!-- ##GET /wallet/:id/tx/last |
|||
|
|||
Get last N wallet transactions. |
|||
|
|||
### HTTP Request |
|||
|
|||
`GET /wallet/:id/tx/last` --> |
@ -0,0 +1,80 @@ |
|||
--- |
|||
title: Bcoin API Reference |
|||
|
|||
home_link: http://bcoin.io |
|||
|
|||
language_tabs: # must be one of https://git.io/vQNgJ |
|||
- shell--curl: cURL |
|||
- shell--cli: CLI |
|||
- javascript |
|||
|
|||
toc_footers: |
|||
- <a href='http://bcoin.io/slack-signup.html'>Join us on Slack</a> |
|||
- <a href='https://github.com/bcoin-org/bcoin'>See the code on GitHub</a> |
|||
- <a href='http://bcoin.io/guides.html'>Browse the guides</a> |
|||
- <a href='http://bcoin.io/docs/index.html'>Full API Documentation</a> |
|||
- <a href='https://github.com/tripit/slate'>Documentation Powered by Slate</a> |
|||
|
|||
includes: |
|||
- clients |
|||
- node |
|||
- node_rpc |
|||
- node_rpc_general |
|||
- node_rpc_chain |
|||
- node_rpc_block |
|||
- node_rpc_mempool |
|||
- node_rpc_tx |
|||
- node_rpc_mining |
|||
- node_rpc_network |
|||
- coin |
|||
- transaction |
|||
- wallet_admin |
|||
- wallet |
|||
- wallet_tx |
|||
- wallet_accounts |
|||
- errors |
|||
|
|||
search: true |
|||
--- |
|||
|
|||
# Introduction |
|||
|
|||
Welcome to the Bcoin API! |
|||
|
|||
The default bcoin HTTP server listens on the standard RPC port (`8332` for main, `18332` for testnet, `48332` for regtest, and `18556` default for simnet). It exposes a REST json api, as well as a JSON-RPC api. |
|||
|
|||
# Authentication |
|||
## Auth |
|||
|
|||
```shell--curl |
|||
curl http://x:[api-key]@127.0.0.1:8332/ |
|||
``` |
|||
|
|||
```shell--cli |
|||
export BCOIN_API_KEY=[api-key] |
|||
bcoin cli info |
|||
``` |
|||
|
|||
```javascript |
|||
const client = new bcoin.http.Client({ |
|||
apiKey: [api-key], |
|||
//... |
|||
}); |
|||
// Or wallet |
|||
const wallet = new bcoin.http.Wallet({ |
|||
apiKey: [api-key], |
|||
//... |
|||
}); |
|||
``` |
|||
|
|||
> Make sure to replace `[api-key]` with your own key. |
|||
|
|||
Auth is accomplished via HTTP Basic Auth, using your node's API key (passed via --api-key). |
|||
|
|||
<aside class="notice"> |
|||
You must replace <code>[api-key]</code> with your personal API key. |
|||
</aside> |
|||
|
|||
<aside class="warning"> |
|||
If you intend to use API via network and setup <code>api-key</code>, make sure to setup <code>ssl</code> too. |
|||
</aside> |
@ -0,0 +1,2 @@ |
|||
//= require ./all_nosearch
|
|||
//= require ./app/_search
|
@ -0,0 +1,16 @@ |
|||
//= require ./lib/_energize
|
|||
//= require ./app/_toc
|
|||
//= require ./app/_lang
|
|||
|
|||
$(function() { |
|||
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10); |
|||
setupLanguages($('body').data('languages')); |
|||
$('.content').imagesLoaded( function() { |
|||
window.recacheHeights(); |
|||
window.refreshToc(); |
|||
}); |
|||
}); |
|||
|
|||
window.onpopstate = function() { |
|||
activateLanguage(getLanguageFromQueryString()); |
|||
}; |
@ -0,0 +1,164 @@ |
|||
//= require ../lib/_jquery
|
|||
|
|||
/* |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0
|
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
|||
*/ |
|||
;(function () { |
|||
'use strict'; |
|||
|
|||
var languages = []; |
|||
|
|||
window.setupLanguages = setupLanguages; |
|||
window.activateLanguage = activateLanguage; |
|||
window.getLanguageFromQueryString = getLanguageFromQueryString; |
|||
|
|||
function activateLanguage(language) { |
|||
if (!language) return; |
|||
if (language === "") return; |
|||
|
|||
$(".lang-selector a").removeClass('active'); |
|||
$(".lang-selector a[data-language-name='" + language + "']").addClass('active'); |
|||
for (var i=0; i < languages.length; i++) { |
|||
$(".highlight.tab-" + languages[i]).hide(); |
|||
$(".lang-specific." + languages[i]).hide(); |
|||
} |
|||
$(".highlight.tab-" + language).show(); |
|||
$(".lang-specific." + language).show(); |
|||
|
|||
window.recacheHeights(); |
|||
|
|||
// scroll to the new location of the position
|
|||
if ($(window.location.hash).get(0)) { |
|||
$(window.location.hash).get(0).scrollIntoView(true); |
|||
} |
|||
} |
|||
|
|||
// parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
|
|||
// MIT licensed
|
|||
// https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
|
|||
function parseURL(str) { |
|||
if (typeof str !== 'string') { |
|||
return {}; |
|||
} |
|||
|
|||
str = str.trim().replace(/^(\?|#|&)/, ''); |
|||
|
|||
if (!str) { |
|||
return {}; |
|||
} |
|||
|
|||
return str.split('&').reduce(function (ret, param) { |
|||
var parts = param.replace(/\+/g, ' ').split('='); |
|||
var key = parts[0]; |
|||
var val = parts[1]; |
|||
|
|||
key = decodeURIComponent(key); |
|||
// missing `=` should be `null`:
|
|||
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
|
|||
val = val === undefined ? null : decodeURIComponent(val); |
|||
|
|||
if (!ret.hasOwnProperty(key)) { |
|||
ret[key] = val; |
|||
} else if (Array.isArray(ret[key])) { |
|||
ret[key].push(val); |
|||
} else { |
|||
ret[key] = [ret[key], val]; |
|||
} |
|||
|
|||
return ret; |
|||
}, {}); |
|||
}; |
|||
|
|||
function stringifyURL(obj) { |
|||
return obj ? Object.keys(obj).sort().map(function (key) { |
|||
var val = obj[key]; |
|||
|
|||
if (Array.isArray(val)) { |
|||
return val.sort().map(function (val2) { |
|||
return encodeURIComponent(key) + '=' + encodeURIComponent(val2); |
|||
}).join('&'); |
|||
} |
|||
|
|||
return encodeURIComponent(key) + '=' + encodeURIComponent(val); |
|||
}).join('&') : ''; |
|||
}; |
|||
|
|||
// gets the language set in the query string
|
|||
function getLanguageFromQueryString() { |
|||
if (location.search.length >= 1) { |
|||
var language = parseURL(location.search).language |
|||
if (language) { |
|||
return language; |
|||
} else if (jQuery.inArray(location.search.substr(1), languages) != -1) { |
|||
return location.search.substr(1); |
|||
} |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
// returns a new query string with the new language in it
|
|||
function generateNewQueryString(language) { |
|||
var url = parseURL(location.search); |
|||
if (url.language) { |
|||
url.language = language; |
|||
return stringifyURL(url); |
|||
} |
|||
return language; |
|||
} |
|||
|
|||
// if a button is clicked, add the state to the history
|
|||
function pushURL(language) { |
|||
if (!history) { return; } |
|||
var hash = window.location.hash; |
|||
if (hash) { |
|||
hash = hash.replace(/^#+/, ''); |
|||
} |
|||
history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash); |
|||
|
|||
// save language as next default
|
|||
localStorage.setItem("language", language); |
|||
} |
|||
|
|||
function setupLanguages(l) { |
|||
var defaultLanguage = localStorage.getItem("language"); |
|||
|
|||
languages = l; |
|||
|
|||
var presetLanguage = getLanguageFromQueryString(); |
|||
if (presetLanguage) { |
|||
// the language is in the URL, so use that language!
|
|||
activateLanguage(presetLanguage); |
|||
|
|||
localStorage.setItem("language", presetLanguage); |
|||
} else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) { |
|||
// the language was the last selected one saved in localstorage, so use that language!
|
|||
activateLanguage(defaultLanguage); |
|||
} else { |
|||
// no language selected, so use the default
|
|||
activateLanguage(languages[0]); |
|||
} |
|||
} |
|||
|
|||
// if we click on a language tab, activate that language
|
|||
$(function() { |
|||
$(".lang-selector a").on("click", function() { |
|||
var language = $(this).data("language-name"); |
|||
pushURL(language); |
|||
activateLanguage(language); |
|||
return false; |
|||
}); |
|||
}); |
|||
})(); |
@ -0,0 +1,98 @@ |
|||
//= require ../lib/_lunr
|
|||
//= require ../lib/_jquery
|
|||
//= require ../lib/_jquery.highlight
|
|||
;(function () { |
|||
'use strict'; |
|||
|
|||
var content, searchResults; |
|||
var highlightOpts = { element: 'span', className: 'search-highlight' }; |
|||
var searchDelay = 0; |
|||
var timeoutHandle = 0; |
|||
|
|||
var index = new lunr.Index(); |
|||
|
|||
index.ref('id'); |
|||
index.field('title', { boost: 10 }); |
|||
index.field('body'); |
|||
index.pipeline.add(lunr.trimmer, lunr.stopWordFilter); |
|||
|
|||
$(populate); |
|||
$(bind); |
|||
|
|||
function populate() { |
|||
$('h1, h2').each(function() { |
|||
var title = $(this); |
|||
var body = title.nextUntil('h1, h2'); |
|||
index.add({ |
|||
id: title.prop('id'), |
|||
title: title.text(), |
|||
body: body.text() |
|||
}); |
|||
}); |
|||
|
|||
determineSearchDelay(); |
|||
} |
|||
function determineSearchDelay() { |
|||
if(index.tokenStore.length>5000) { |
|||
searchDelay = 300; |
|||
} |
|||
} |
|||
|
|||
function bind() { |
|||
content = $('.content'); |
|||
searchResults = $('.search-results'); |
|||
|
|||
$('#input-search').on('keyup',function(e) { |
|||
var wait = function() { |
|||
return function(executingFunction, waitTime){ |
|||
clearTimeout(timeoutHandle); |
|||
timeoutHandle = setTimeout(executingFunction, waitTime); |
|||
}; |
|||
}(); |
|||
wait(function(){ |
|||
search(e); |
|||
}, searchDelay ); |
|||
}); |
|||
} |
|||
|
|||
function search(event) { |
|||
|
|||
var searchInput = $('#input-search')[0]; |
|||
|
|||
unhighlight(); |
|||
searchResults.addClass('visible'); |
|||
|
|||
// ESC clears the field
|
|||
if (event.keyCode === 27) searchInput.value = ''; |
|||
|
|||
if (searchInput.value) { |
|||
var results = index.search(searchInput.value).filter(function(r) { |
|||
return r.score > 0.0001; |
|||
}); |
|||
|
|||
if (results.length) { |
|||
searchResults.empty(); |
|||
$.each(results, function (index, result) { |
|||
var elem = document.getElementById(result.ref); |
|||
searchResults.append("<li><a href='#" + result.ref + "'>" + $(elem).text() + "</a></li>"); |
|||
}); |
|||
highlight.call(searchInput); |
|||
} else { |
|||
searchResults.html('<li></li>'); |
|||
$('.search-results li').text('No Results Found for "' + searchInput.value + '"'); |
|||
} |
|||
} else { |
|||
unhighlight(); |
|||
searchResults.removeClass('visible'); |
|||
} |
|||
} |
|||
|
|||
function highlight() { |
|||
if (this.value) content.highlight(this.value, highlightOpts); |
|||
} |
|||
|
|||
function unhighlight() { |
|||
content.unhighlight(highlightOpts); |
|||
} |
|||
})(); |
|||
|
@ -0,0 +1,117 @@ |
|||
//= require ../lib/_jquery
|
|||
//= require ../lib/_imagesloaded.min
|
|||
;(function () { |
|||
'use strict'; |
|||
|
|||
var loaded = false; |
|||
|
|||
var debounce = function(func, waitTime) { |
|||
var timeout = false; |
|||
return function() { |
|||
if (timeout === false) { |
|||
setTimeout(function() { |
|||
func(); |
|||
timeout = false; |
|||
}, waitTime); |
|||
timeout = true; |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
var closeToc = function() { |
|||
$(".toc-wrapper").removeClass('open'); |
|||
$("#nav-button").removeClass('open'); |
|||
}; |
|||
|
|||
function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) { |
|||
var headerHeights = {}; |
|||
var pageHeight = 0; |
|||
var windowHeight = 0; |
|||
var originalTitle = document.title; |
|||
|
|||
var recacheHeights = function() { |
|||
headerHeights = {}; |
|||
pageHeight = $(document).height(); |
|||
windowHeight = $(window).height(); |
|||
|
|||
$toc.find(tocLinkSelector).each(function() { |
|||
var targetId = $(this).attr('href'); |
|||
if (targetId[0] === "#") { |
|||
headerHeights[targetId] = $(targetId).offset().top; |
|||
} |
|||
}); |
|||
}; |
|||
|
|||
var refreshToc = function() { |
|||
var currentTop = $(document).scrollTop() + scrollOffset; |
|||
|
|||
if (currentTop + windowHeight >= pageHeight) { |
|||
// at bottom of page, so just select last header by making currentTop very large
|
|||
// this fixes the problem where the last header won't ever show as active if its content
|
|||
// is shorter than the window height
|
|||
currentTop = pageHeight + 1000; |
|||
} |
|||
|
|||
var best = null; |
|||
for (var name in headerHeights) { |
|||
if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) { |
|||
best = name; |
|||
} |
|||
} |
|||
|
|||
// Catch the initial load case
|
|||
if (currentTop == scrollOffset && !loaded) { |
|||
best = window.location.hash; |
|||
loaded = true; |
|||
} |
|||
|
|||
var $best = $toc.find("[href='" + best + "']").first(); |
|||
if (!$best.hasClass("active")) { |
|||
// .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
|
|||
// .active-expanded is applied to the ToC links that are parents of this one
|
|||
$toc.find(".active").removeClass("active"); |
|||
$toc.find(".active-parent").removeClass("active-parent"); |
|||
$best.addClass("active"); |
|||
$best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent'); |
|||
$best.siblings(tocListSelector).addClass("active"); |
|||
$toc.find(tocListSelector).filter(":not(.active)").slideUp(150); |
|||
$toc.find(tocListSelector).filter(".active").slideDown(150); |
|||
if (window.history.pushState) { |
|||
window.history.pushState(null, "", best); |
|||
} |
|||
// TODO remove classnames
|
|||
document.title = $best.data("title") + " – " + originalTitle; |
|||
} |
|||
}; |
|||
|
|||
var makeToc = function() { |
|||
recacheHeights(); |
|||
refreshToc(); |
|||
|
|||
$("#nav-button").click(function() { |
|||
$(".toc-wrapper").toggleClass('open'); |
|||
$("#nav-button").toggleClass('open'); |
|||
return false; |
|||
}); |
|||
$(".page-wrapper").click(closeToc); |
|||
$(".toc-link").click(closeToc); |
|||
|
|||
// reload immediately after scrolling on toc click
|
|||
$toc.find(tocLinkSelector).click(function() { |
|||
setTimeout(function() { |
|||
refreshToc(); |
|||
}, 0); |
|||
}); |
|||
|
|||
$(window).scroll(debounce(refreshToc, 200)); |
|||
$(window).resize(debounce(recacheHeights, 200)); |
|||
}; |
|||
|
|||
makeToc(); |
|||
|
|||
window.recacheHeights = recacheHeights; |
|||
window.refreshToc = refreshToc; |
|||
} |
|||
|
|||
window.loadToc = loadToc; |
|||
})(); |
@ -0,0 +1,169 @@ |
|||
/** |
|||
* energize.js v0.1.0 |
|||
* |
|||
* Speeds up click events on mobile devices. |
|||
* https://github.com/davidcalhoun/energize.js
|
|||
*/ |
|||
|
|||
(function() { // Sandbox
|
|||
/** |
|||
* Don't add to non-touch devices, which don't need to be sped up |
|||
*/ |
|||
if(!('ontouchstart' in window)) return; |
|||
|
|||
var lastClick = {}, |
|||
isThresholdReached, touchstart, touchmove, touchend, |
|||
click, closest; |
|||
|
|||
/** |
|||
* isThresholdReached |
|||
* |
|||
* Compare touchstart with touchend xy coordinates, |
|||
* and only fire simulated click event if the coordinates |
|||
* are nearby. (don't want clicking to be confused with a swipe) |
|||
*/ |
|||
isThresholdReached = function(startXY, xy) { |
|||
return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5; |
|||
}; |
|||
|
|||
/** |
|||
* touchstart |
|||
* |
|||
* Save xy coordinates when the user starts touching the screen |
|||
*/ |
|||
touchstart = function(e) { |
|||
this.startXY = [e.touches[0].clientX, e.touches[0].clientY]; |
|||
this.threshold = false; |
|||
}; |
|||
|
|||
/** |
|||
* touchmove |
|||
* |
|||
* Check if the user is scrolling past the threshold. |
|||
* Have to check here because touchend will not always fire |
|||
* on some tested devices (Kindle Fire?) |
|||
*/ |
|||
touchmove = function(e) { |
|||
// NOOP if the threshold has already been reached
|
|||
if(this.threshold) return false; |
|||
|
|||
this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]); |
|||
}; |
|||
|
|||
/** |
|||
* touchend |
|||
* |
|||
* If the user didn't scroll past the threshold between |
|||
* touchstart and touchend, fire a simulated click. |
|||
* |
|||
* (This will fire before a native click) |
|||
*/ |
|||
touchend = function(e) { |
|||
// Don't fire a click if the user scrolled past the threshold
|
|||
if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) { |
|||
return; |
|||
} |
|||
|
|||
/** |
|||
* Create and fire a click event on the target element |
|||
* https://developer.mozilla.org/en/DOM/event.initMouseEvent
|
|||
*/ |
|||
var touch = e.changedTouches[0], |
|||
evt = document.createEvent('MouseEvents'); |
|||
evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); |
|||
evt.simulated = true; // distinguish from a normal (nonsimulated) click
|
|||
e.target.dispatchEvent(evt); |
|||
}; |
|||
|
|||
/** |
|||
* click |
|||
* |
|||
* Because we've already fired a click event in touchend, |
|||
* we need to listed for all native click events here |
|||
* and suppress them as necessary. |
|||
*/ |
|||
click = function(e) { |
|||
/** |
|||
* Prevent ghost clicks by only allowing clicks we created |
|||
* in the click event we fired (look for e.simulated) |
|||
*/ |
|||
var time = Date.now(), |
|||
timeDiff = time - lastClick.time, |
|||
x = e.clientX, |
|||
y = e.clientY, |
|||
xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)], |
|||
target = closest(e.target, 'A') || e.target, // needed for standalone apps
|
|||
nodeName = target.nodeName, |
|||
isLink = nodeName === 'A', |
|||
standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href"); |
|||
|
|||
lastClick.time = time; |
|||
lastClick.x = x; |
|||
lastClick.y = y; |
|||
|
|||
/** |
|||
* Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire), |
|||
* so we have to add more logic to determine the time of the last click. Not perfect... |
|||
* |
|||
* Older, simpler check: if((!e.simulated) || standAlone) |
|||
*/ |
|||
if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) { |
|||
e.preventDefault(); |
|||
e.stopPropagation(); |
|||
if(!standAlone) return false; |
|||
} |
|||
|
|||
/** |
|||
* Special logic for standalone web apps |
|||
* See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
|
|||
*/ |
|||
if(standAlone) { |
|||
window.location = target.getAttribute("href"); |
|||
} |
|||
|
|||
/** |
|||
* Add an energize-focus class to the targeted link (mimics :focus behavior) |
|||
* TODO: test and/or remove? Does this work? |
|||
*/ |
|||
if(!target || !target.classList) return; |
|||
target.classList.add("energize-focus"); |
|||
window.setTimeout(function(){ |
|||
target.classList.remove("energize-focus"); |
|||
}, 150); |
|||
}; |
|||
|
|||
/** |
|||
* closest |
|||
* @param {HTMLElement} node current node to start searching from. |
|||
* @param {string} tagName the (uppercase) name of the tag you're looking for. |
|||
* |
|||
* Find the closest ancestor tag of a given node. |
|||
* |
|||
* Starts at node and goes up the DOM tree looking for a |
|||
* matching nodeName, continuing until hitting document.body |
|||
*/ |
|||
closest = function(node, tagName){ |
|||
var curNode = node; |
|||
|
|||
while(curNode !== document.body) { // go up the dom until we find the tag we're after
|
|||
if(!curNode || curNode.nodeName === tagName) { return curNode; } // found
|
|||
curNode = curNode.parentNode; // not found, so keep going up
|
|||
} |
|||
|
|||
return null; // not found
|
|||
}; |
|||
|
|||
/** |
|||
* Add all delegated event listeners |
|||
* |
|||
* All the events we care about bubble up to document, |
|||
* so we can take advantage of event delegation. |
|||
* |
|||
* Note: no need to wait for DOMContentLoaded here |
|||
*/ |
|||
document.addEventListener('touchstart', touchstart, false); |
|||
document.addEventListener('touchmove', touchmove, false); |
|||
document.addEventListener('touchend', touchend, false); |
|||
document.addEventListener('click', click, true); // TODO: why does this use capture?
|
|||
|
|||
})(); |
File diff suppressed because one or more lines are too long
@ -0,0 +1,108 @@ |
|||
/* |
|||
* jQuery Highlight plugin |
|||
* |
|||
* Based on highlight v3 by Johann Burkard |
|||
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
|
|||
* |
|||
* Code a little bit refactored and cleaned (in my humble opinion). |
|||
* Most important changes: |
|||
* - has an option to highlight only entire words (wordsOnly - false by default), |
|||
* - has an option to be case sensitive (caseSensitive - false by default) |
|||
* - highlight element tag and class names can be specified in options |
|||
* |
|||
* Usage: |
|||
* // wrap every occurrance of text 'lorem' in content
|
|||
* // with <span class='highlight'> (default options)
|
|||
* $('#content').highlight('lorem'); |
|||
* |
|||
* // search for and highlight more terms at once
|
|||
* // so you can save some time on traversing DOM
|
|||
* $('#content').highlight(['lorem', 'ipsum']); |
|||
* $('#content').highlight('lorem ipsum'); |
|||
* |
|||
* // search only for entire word 'lorem'
|
|||
* $('#content').highlight('lorem', { wordsOnly: true }); |
|||
* |
|||
* // don't ignore case during search of term 'lorem'
|
|||
* $('#content').highlight('lorem', { caseSensitive: true }); |
|||
* |
|||
* // wrap every occurrance of term 'ipsum' in content
|
|||
* // with <em class='important'>
|
|||
* $('#content').highlight('ipsum', { element: 'em', className: 'important' }); |
|||
* |
|||
* // remove default highlight
|
|||
* $('#content').unhighlight(); |
|||
* |
|||
* // remove custom highlight
|
|||
* $('#content').unhighlight({ element: 'em', className: 'important' }); |
|||
* |
|||
* |
|||
* Copyright (c) 2009 Bartek Szopka |
|||
* |
|||
* Licensed under MIT license. |
|||
* |
|||
*/ |
|||
|
|||
jQuery.extend({ |
|||
highlight: function (node, re, nodeName, className) { |
|||
if (node.nodeType === 3) { |
|||
var match = node.data.match(re); |
|||
if (match) { |
|||
var highlight = document.createElement(nodeName || 'span'); |
|||
highlight.className = className || 'highlight'; |
|||
var wordNode = node.splitText(match.index); |
|||
wordNode.splitText(match[0].length); |
|||
var wordClone = wordNode.cloneNode(true); |
|||
highlight.appendChild(wordClone); |
|||
wordNode.parentNode.replaceChild(highlight, wordNode); |
|||
return 1; //skip added node in parent
|
|||
} |
|||
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
|
|||
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
|
|||
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
|
|||
for (var i = 0; i < node.childNodes.length; i++) { |
|||
i += jQuery.highlight(node.childNodes[i], re, nodeName, className); |
|||
} |
|||
} |
|||
return 0; |
|||
} |
|||
}); |
|||
|
|||
jQuery.fn.unhighlight = function (options) { |
|||
var settings = { className: 'highlight', element: 'span' }; |
|||
jQuery.extend(settings, options); |
|||
|
|||
return this.find(settings.element + "." + settings.className).each(function () { |
|||
var parent = this.parentNode; |
|||
parent.replaceChild(this.firstChild, this); |
|||
parent.normalize(); |
|||
}).end(); |
|||
}; |
|||
|
|||
jQuery.fn.highlight = function (words, options) { |
|||
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false }; |
|||
jQuery.extend(settings, options); |
|||
|
|||
if (words.constructor === String) { |
|||
words = [words]; |
|||
} |
|||
words = jQuery.grep(words, function(word, i){ |
|||
return word != ''; |
|||
}); |
|||
words = jQuery.map(words, function(word, i) { |
|||
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); |
|||
}); |
|||
if (words.length == 0) { return this; }; |
|||
|
|||
var flag = settings.caseSensitive ? "" : "i"; |
|||
var pattern = "(" + words.join("|") + ")"; |
|||
if (settings.wordsOnly) { |
|||
pattern = "\\b" + pattern + "\\b"; |
|||
} |
|||
var re = new RegExp(pattern, flag); |
|||
|
|||
return this.each(function () { |
|||
jQuery.highlight(this, re, settings.element, settings.className); |
|||
}); |
|||
}; |
|||
|
File diff suppressed because it is too large
File diff suppressed because it is too large
@ -0,0 +1,122 @@ |
|||
<%# |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
|||
%> |
|||
<% language_tabs = current_page.data.language_tabs || [] %> |
|||
<% page_content = yield %> |
|||
<% |
|||
if current_page.data.includes |
|||
current_page.data.includes.each do |include| |
|||
page_content += partial("includes/#{include}") |
|||
end |
|||
end |
|||
%> |
|||
|
|||
<!doctype html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
|||
<title><%= current_page.data.title || "API Documentation" %></title> |
|||
|
|||
<style> |
|||
<%= Rouge::Themes::MonokaiSublime.render(:scope => '.highlight') %> |
|||
</style> |
|||
<%= stylesheet_link_tag :screen, media: :screen %> |
|||
<%= stylesheet_link_tag :print, media: :print %> |
|||
<% if current_page.data.search %> |
|||
<%= javascript_include_tag "all" %> |
|||
<% else %> |
|||
<%= javascript_include_tag "all_nosearch" %> |
|||
<% end %> |
|||
</head> |
|||
|
|||
<body class="<%= page_classes %>" data-languages="<%=h language_tabs.map{ |lang| lang.is_a?(Hash) ? lang.keys.first : lang }.to_json %>"> |
|||
<a href="#" id="nav-button"> |
|||
<span> |
|||
NAV |
|||
<%= image_tag('navbar.png') %> |
|||
</span> |
|||
</a> |
|||
<div class="toc-wrapper"> |
|||
<% if current_page.data.home_link %> |
|||
<a href="<%= current_page.data.home_link %>"> |
|||
<% end %> |
|||
<%= image_tag "logo.png", class: 'logo' %> |
|||
<% if current_page.data.home_link %> |
|||
</a> |
|||
<% end %> |
|||
<% if language_tabs.any? %> |
|||
<div class="lang-selector"> |
|||
<% language_tabs.each do |lang| %> |
|||
<% if lang.is_a? Hash %> |
|||
<a href="#" data-language-name="<%= lang.keys.first %>"><%= lang.values.first %></a> |
|||
<% else %> |
|||
<a href="#" data-language-name="<%= lang %>"><%= lang %></a> |
|||
<% end %> |
|||
<% end %> |
|||
</div> |
|||
<% end %> |
|||
<% if current_page.data.search %> |
|||
<div class="search"> |
|||
<input type="text" class="search" id="input-search" placeholder="Search"> |
|||
</div> |
|||
<ul class="search-results"></ul> |
|||
<% end %> |
|||
<div id="toc" class="toc-list-h1"> |
|||
<% toc_data(page_content).each do |h1| %> |
|||
<li> |
|||
<a href="#<%= h1[:id] %>" class="toc-h1 toc-link" data-title="<%= h1[:content] %>"><%= h1[:content] %></a> |
|||
<% if h1[:children].length > 0 %> |
|||
<ul class="toc-list-h2"> |
|||
<% h1[:children].each do |h2| %> |
|||
<li> |
|||
<a href="#<%= h2[:id] %>" class="toc-h2 toc-link" data-title="<%= h1[:content] %>"><%= h2[:content] %></a> |
|||
</li> |
|||
<% end %> |
|||
</ul> |
|||
<% end %> |
|||
</li> |
|||
<% end %> |
|||
</div> |
|||
<% if current_page.data.toc_footers %> |
|||
<ul class="toc-footer"> |
|||
<% current_page.data.toc_footers.each do |footer| %> |
|||
<li><%= footer %></li> |
|||
<% end %> |
|||
</ul> |
|||
<% end %> |
|||
</div> |
|||
<div class="page-wrapper"> |
|||
<div class="dark-box"></div> |
|||
<div class="content"> |
|||
<%= page_content %> |
|||
</div> |
|||
<div class="dark-box"> |
|||
<% if language_tabs.any? %> |
|||
<div class="lang-selector"> |
|||
<% language_tabs.each do |lang| %> |
|||
<% if lang.is_a? Hash %> |
|||
<a href="#" data-language-name="<%= lang.keys.first %>"><%= lang.values.first %></a> |
|||
<% else %> |
|||
<a href="#" data-language-name="<%= lang %>"><%= lang %></a> |
|||
<% end %> |
|||
<% end %> |
|||
</div> |
|||
<% end %> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,48 @@ |
|||
.page-wrapper { |
|||
background-color: #dadee0; |
|||
} |
|||
|
|||
.toc-wrapper .logo { |
|||
width: 60%; |
|||
margin: 20px 0 20px 15px; |
|||
} |
|||
|
|||
.highlight .s1 { |
|||
color: #c991f9; |
|||
} |
|||
|
|||
.highlight .s2 { |
|||
color: #b0faff; |
|||
} |
|||
|
|||
.highlight .nb { |
|||
color: #ffa900; |
|||
} |
|||
|
|||
.highlight .o { |
|||
color: #ff005c; |
|||
} |
|||
|
|||
.highlight .kc { |
|||
color: #29adff; |
|||
} |
|||
|
|||
.highlight .na { |
|||
color: #ccec8a; |
|||
} |
|||
|
|||
.page-wrapper .dark-box { |
|||
background-color: #474f52; |
|||
} |
|||
|
|||
.content aside { |
|||
background: #b3c4fb; |
|||
} |
|||
|
|||
.content aside.warning { |
|||
background-color: #c0b3f3; |
|||
} |
|||
|
|||
.toc-wrapper .toc-link.active { |
|||
background-color: #5659dc; |
|||
} |
@ -0,0 +1,38 @@ |
|||
@font-face { |
|||
font-family: 'slate'; |
|||
src:font-url('slate.eot?-syv14m'); |
|||
src:font-url('slate.eot?#iefix-syv14m') format('embedded-opentype'), |
|||
font-url('slate.woff2?-syv14m') format('woff2'), |
|||
font-url('slate.woff?-syv14m') format('woff'), |
|||
font-url('slate.ttf?-syv14m') format('truetype'), |
|||
font-url('slate.svg?-syv14m#slate') format('svg'); |
|||
font-weight: normal; |
|||
font-style: normal; |
|||
} |
|||
|
|||
%icon { |
|||
font-family: 'slate'; |
|||
speak: none; |
|||
font-style: normal; |
|||
font-weight: normal; |
|||
font-variant: normal; |
|||
text-transform: none; |
|||
line-height: 1; |
|||
} |
|||
|
|||
%icon-exclamation-sign { |
|||
@extend %icon; |
|||
content: "\e600"; |
|||
} |
|||
%icon-info-sign { |
|||
@extend %icon; |
|||
content: "\e602"; |
|||
} |
|||
%icon-ok-sign { |
|||
@extend %icon; |
|||
content: "\e606"; |
|||
} |
|||
%icon-search { |
|||
@extend %icon; |
|||
content: "\e607"; |
|||
} |
@ -0,0 +1,427 @@ |
|||
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */ |
|||
|
|||
/** |
|||
* 1. Set default font family to sans-serif. |
|||
* 2. Prevent iOS text size adjust after orientation change, without disabling |
|||
* user zoom. |
|||
*/ |
|||
|
|||
html { |
|||
font-family: sans-serif; /* 1 */ |
|||
-ms-text-size-adjust: 100%; /* 2 */ |
|||
-webkit-text-size-adjust: 100%; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove default margin. |
|||
*/ |
|||
|
|||
body { |
|||
margin: 0; |
|||
} |
|||
|
|||
/* HTML5 display definitions |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Correct `block` display not defined for any HTML5 element in IE 8/9. |
|||
* Correct `block` display not defined for `details` or `summary` in IE 10/11 |
|||
* and Firefox. |
|||
* Correct `block` display not defined for `main` in IE 11. |
|||
*/ |
|||
|
|||
article, |
|||
aside, |
|||
details, |
|||
figcaption, |
|||
figure, |
|||
footer, |
|||
header, |
|||
hgroup, |
|||
main, |
|||
menu, |
|||
nav, |
|||
section, |
|||
summary { |
|||
display: block; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct `inline-block` display not defined in IE 8/9. |
|||
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. |
|||
*/ |
|||
|
|||
audio, |
|||
canvas, |
|||
progress, |
|||
video { |
|||
display: inline-block; /* 1 */ |
|||
vertical-align: baseline; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Prevent modern browsers from displaying `audio` without controls. |
|||
* Remove excess height in iOS 5 devices. |
|||
*/ |
|||
|
|||
audio:not([controls]) { |
|||
display: none; |
|||
height: 0; |
|||
} |
|||
|
|||
/** |
|||
* Address `[hidden]` styling not present in IE 8/9/10. |
|||
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. |
|||
*/ |
|||
|
|||
[hidden], |
|||
template { |
|||
display: none; |
|||
} |
|||
|
|||
/* Links |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove the gray background color from active links in IE 10. |
|||
*/ |
|||
|
|||
a { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
/** |
|||
* Improve readability when focused and also mouse hovered in all browsers. |
|||
*/ |
|||
|
|||
a:active, |
|||
a:hover { |
|||
outline: 0; |
|||
} |
|||
|
|||
/* Text-level semantics |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Address styling not present in IE 8/9/10/11, Safari, and Chrome. |
|||
*/ |
|||
|
|||
abbr[title] { |
|||
border-bottom: 1px dotted; |
|||
} |
|||
|
|||
/** |
|||
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome. |
|||
*/ |
|||
|
|||
b, |
|||
strong { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
/** |
|||
* Address styling not present in Safari and Chrome. |
|||
*/ |
|||
|
|||
dfn { |
|||
font-style: italic; |
|||
} |
|||
|
|||
/** |
|||
* Address variable `h1` font-size and margin within `section` and `article` |
|||
* contexts in Firefox 4+, Safari, and Chrome. |
|||
*/ |
|||
|
|||
h1 { |
|||
font-size: 2em; |
|||
margin: 0.67em 0; |
|||
} |
|||
|
|||
/** |
|||
* Address styling not present in IE 8/9. |
|||
*/ |
|||
|
|||
mark { |
|||
background: #ff0; |
|||
color: #000; |
|||
} |
|||
|
|||
/** |
|||
* Address inconsistent and variable font size in all browsers. |
|||
*/ |
|||
|
|||
small { |
|||
font-size: 80%; |
|||
} |
|||
|
|||
/** |
|||
* Prevent `sub` and `sup` affecting `line-height` in all browsers. |
|||
*/ |
|||
|
|||
sub, |
|||
sup { |
|||
font-size: 75%; |
|||
line-height: 0; |
|||
position: relative; |
|||
vertical-align: baseline; |
|||
} |
|||
|
|||
sup { |
|||
top: -0.5em; |
|||
} |
|||
|
|||
sub { |
|||
bottom: -0.25em; |
|||
} |
|||
|
|||
/* Embedded content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove border when inside `a` element in IE 8/9/10. |
|||
*/ |
|||
|
|||
img { |
|||
border: 0; |
|||
} |
|||
|
|||
/** |
|||
* Correct overflow not hidden in IE 9/10/11. |
|||
*/ |
|||
|
|||
svg:not(:root) { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* Grouping content |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Address margin not present in IE 8/9 and Safari. |
|||
*/ |
|||
|
|||
figure { |
|||
margin: 1em 40px; |
|||
} |
|||
|
|||
/** |
|||
* Address differences between Firefox and other browsers. |
|||
*/ |
|||
|
|||
hr { |
|||
-moz-box-sizing: content-box; |
|||
box-sizing: content-box; |
|||
height: 0; |
|||
} |
|||
|
|||
/** |
|||
* Contain overflow in all browsers. |
|||
*/ |
|||
|
|||
pre { |
|||
overflow: auto; |
|||
} |
|||
|
|||
/** |
|||
* Address odd `em`-unit font size rendering in all browsers. |
|||
*/ |
|||
|
|||
code, |
|||
kbd, |
|||
pre, |
|||
samp { |
|||
font-family: monospace, monospace; |
|||
font-size: 1em; |
|||
} |
|||
|
|||
/* Forms |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Known limitation: by default, Chrome and Safari on OS X allow very limited |
|||
* styling of `select`, unless a `border` property is set. |
|||
*/ |
|||
|
|||
/** |
|||
* 1. Correct color not being inherited. |
|||
* Known issue: affects color of disabled elements. |
|||
* 2. Correct font properties not being inherited. |
|||
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome. |
|||
*/ |
|||
|
|||
button, |
|||
input, |
|||
optgroup, |
|||
select, |
|||
textarea { |
|||
color: inherit; /* 1 */ |
|||
font: inherit; /* 2 */ |
|||
margin: 0; /* 3 */ |
|||
} |
|||
|
|||
/** |
|||
* Address `overflow` set to `hidden` in IE 8/9/10/11. |
|||
*/ |
|||
|
|||
button { |
|||
overflow: visible; |
|||
} |
|||
|
|||
/** |
|||
* Address inconsistent `text-transform` inheritance for `button` and `select`. |
|||
* All other form control elements do not inherit `text-transform` values. |
|||
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. |
|||
* Correct `select` style inheritance in Firefox. |
|||
*/ |
|||
|
|||
button, |
|||
select { |
|||
text-transform: none; |
|||
} |
|||
|
|||
/** |
|||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` |
|||
* and `video` controls. |
|||
* 2. Correct inability to style clickable `input` types in iOS. |
|||
* 3. Improve usability and consistency of cursor style between image-type |
|||
* `input` and others. |
|||
*/ |
|||
|
|||
button, |
|||
html input[type="button"], /* 1 */ |
|||
input[type="reset"], |
|||
input[type="submit"] { |
|||
-webkit-appearance: button; /* 2 */ |
|||
cursor: pointer; /* 3 */ |
|||
} |
|||
|
|||
/** |
|||
* Re-set default cursor for disabled elements. |
|||
*/ |
|||
|
|||
button[disabled], |
|||
html input[disabled] { |
|||
cursor: default; |
|||
} |
|||
|
|||
/** |
|||
* Remove inner padding and border in Firefox 4+. |
|||
*/ |
|||
|
|||
button::-moz-focus-inner, |
|||
input::-moz-focus-inner { |
|||
border: 0; |
|||
padding: 0; |
|||
} |
|||
|
|||
/** |
|||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in |
|||
* the UA stylesheet. |
|||
*/ |
|||
|
|||
input { |
|||
line-height: normal; |
|||
} |
|||
|
|||
/** |
|||
* It's recommended that you don't attempt to style these elements. |
|||
* Firefox's implementation doesn't respect box-sizing, padding, or width. |
|||
* |
|||
* 1. Address box sizing set to `content-box` in IE 8/9/10. |
|||
* 2. Remove excess padding in IE 8/9/10. |
|||
*/ |
|||
|
|||
input[type="checkbox"], |
|||
input[type="radio"] { |
|||
box-sizing: border-box; /* 1 */ |
|||
padding: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Fix the cursor style for Chrome's increment/decrement buttons. For certain |
|||
* `font-size` values of the `input`, it causes the cursor style of the |
|||
* decrement button to change from `default` to `text`. |
|||
*/ |
|||
|
|||
input[type="number"]::-webkit-inner-spin-button, |
|||
input[type="number"]::-webkit-outer-spin-button { |
|||
height: auto; |
|||
} |
|||
|
|||
/** |
|||
* 1. Address `appearance` set to `searchfield` in Safari and Chrome. |
|||
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome |
|||
* (include `-moz` to future-proof). |
|||
*/ |
|||
|
|||
input[type="search"] { |
|||
-webkit-appearance: textfield; /* 1 */ |
|||
-moz-box-sizing: content-box; |
|||
-webkit-box-sizing: content-box; /* 2 */ |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
/** |
|||
* Remove inner padding and search cancel button in Safari and Chrome on OS X. |
|||
* Safari (but not Chrome) clips the cancel button when the search input has |
|||
* padding (and `textfield` appearance). |
|||
*/ |
|||
|
|||
input[type="search"]::-webkit-search-cancel-button, |
|||
input[type="search"]::-webkit-search-decoration { |
|||
-webkit-appearance: none; |
|||
} |
|||
|
|||
/** |
|||
* Define consistent border, margin, and padding. |
|||
*/ |
|||
|
|||
fieldset { |
|||
border: 1px solid #c0c0c0; |
|||
margin: 0 2px; |
|||
padding: 0.35em 0.625em 0.75em; |
|||
} |
|||
|
|||
/** |
|||
* 1. Correct `color` not being inherited in IE 8/9/10/11. |
|||
* 2. Remove padding so people aren't caught out if they zero out fieldsets. |
|||
*/ |
|||
|
|||
legend { |
|||
border: 0; /* 1 */ |
|||
padding: 0; /* 2 */ |
|||
} |
|||
|
|||
/** |
|||
* Remove default vertical scrollbar in IE 8/9/10/11. |
|||
*/ |
|||
|
|||
textarea { |
|||
overflow: auto; |
|||
} |
|||
|
|||
/** |
|||
* Don't inherit the `font-weight` (applied by a rule above). |
|||
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X. |
|||
*/ |
|||
|
|||
optgroup { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
/* Tables |
|||
========================================================================== */ |
|||
|
|||
/** |
|||
* Remove most spacing between table cells. |
|||
*/ |
|||
|
|||
table { |
|||
border-collapse: collapse; |
|||
border-spacing: 0; |
|||
} |
|||
|
|||
td, |
|||
th { |
|||
padding: 0; |
|||
} |
@ -0,0 +1,103 @@ |
|||
/* |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
|||
*/ |
|||
|
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// CUSTOMIZE SLATE |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// Use these settings to help adjust the appearance of Slate |
|||
|
|||
|
|||
// BACKGROUND COLORS |
|||
//////////////////// |
|||
$nav-bg: #2E3336 !default; |
|||
$examples-bg: #2E3336 !default; |
|||
$code-bg: #1E2224 !default; |
|||
$code-annotation-bg: #191D1F !default; |
|||
$nav-subitem-bg: #1E2224 !default; |
|||
$nav-active-bg: #0F75D4 !default; |
|||
$nav-active-parent-bg: #1E2224 !default; // parent links of the current section |
|||
$lang-select-border: #000 !default; |
|||
$lang-select-bg: #1E2224 !default; |
|||
$lang-select-active-bg: $examples-bg !default; // feel free to change this to blue or something |
|||
$lang-select-pressed-bg: #111 !default; // color of language tab bg when mouse is pressed |
|||
$main-bg: #F3F7F9 !default; |
|||
$aside-notice-bg: #8fbcd4 !default; |
|||
$aside-warning-bg: #c97a7e !default; |
|||
$aside-success-bg: #6ac174 !default; |
|||
$search-notice-bg: #c97a7e !default; |
|||
|
|||
|
|||
// TEXT COLORS |
|||
//////////////////// |
|||
$main-text: #333 !default; // main content text color |
|||
$nav-text: #fff !default; |
|||
$nav-active-text: #fff !default; |
|||
$nav-active-parent-text: #fff !default; // parent links of the current section |
|||
$lang-select-text: #fff !default; // color of unselected language tab text |
|||
$lang-select-active-text: #fff !default; // color of selected language tab text |
|||
$lang-select-pressed-text: #fff !default; // color of language tab text when mouse is pressed |
|||
|
|||
|
|||
// SIZES |
|||
//////////////////// |
|||
$nav-width: 230px !default; // width of the navbar |
|||
$examples-width: 50% !default; // portion of the screen taken up by code examples |
|||
$logo-margin: 0px !default; // margin below logo |
|||
$main-padding: 28px !default; // padding to left and right of content & examples |
|||
$nav-padding: 15px !default; // padding to left and right of navbar |
|||
$nav-v-padding: 10px !default; // padding used vertically around search boxes and results |
|||
$nav-indent: 10px !default; // extra padding for ToC subitems |
|||
$code-annotation-padding: 13px !default; // padding inside code annotations |
|||
$h1-margin-bottom: 21px !default; // padding under the largest header tags |
|||
$tablet-width: 930px !default; // min width before reverting to tablet size |
|||
$phone-width: $tablet-width - $nav-width !default; // min width before reverting to mobile size |
|||
|
|||
|
|||
// FONTS |
|||
//////////////////// |
|||
%default-font { |
|||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
%header-font { |
|||
@extend %default-font; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
%code-font { |
|||
font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif; |
|||
font-size: 12px; |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
|
|||
// OTHER |
|||
//////////////////// |
|||
$nav-footer-border-color: #666 !default; |
|||
$search-box-border-color: #666 !default; |
|||
|
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// INTERNAL |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// These settings are probably best left alone. |
|||
|
|||
%break-words { |
|||
word-break: break-all; |
|||
hyphens: auto; |
|||
} |
@ -0,0 +1,147 @@ |
|||
@charset "utf-8"; |
|||
@import 'normalize'; |
|||
@import 'variables'; |
|||
@import 'icon-font'; |
|||
|
|||
/* |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
|||
*/ |
|||
|
|||
$print-color: #999; |
|||
$print-color-light: #ccc; |
|||
$print-font-size: 12px; |
|||
|
|||
body { |
|||
@extend %default-font; |
|||
} |
|||
|
|||
.tocify, .toc-footer, .lang-selector, .search, #nav-button { |
|||
display: none; |
|||
} |
|||
|
|||
.tocify-wrapper>img { |
|||
margin: 0 auto; |
|||
display: block; |
|||
} |
|||
|
|||
.content { |
|||
font-size: 12px; |
|||
|
|||
pre, code { |
|||
@extend %code-font; |
|||
@extend %break-words; |
|||
border: 1px solid $print-color; |
|||
border-radius: 5px; |
|||
font-size: 0.8em; |
|||
} |
|||
|
|||
pre { |
|||
code { |
|||
border: 0; |
|||
} |
|||
} |
|||
|
|||
pre { |
|||
padding: 1.3em; |
|||
} |
|||
|
|||
code { |
|||
padding: 0.2em; |
|||
} |
|||
|
|||
table { |
|||
border: 1px solid $print-color; |
|||
tr { |
|||
border-bottom: 1px solid $print-color; |
|||
} |
|||
td,th { |
|||
padding: 0.7em; |
|||
} |
|||
} |
|||
|
|||
p { |
|||
line-height: 1.5; |
|||
} |
|||
|
|||
a { |
|||
text-decoration: none; |
|||
color: #000; |
|||
} |
|||
|
|||
h1 { |
|||
@extend %header-font; |
|||
font-size: 2.5em; |
|||
padding-top: 0.5em; |
|||
padding-bottom: 0.5em; |
|||
margin-top: 1em; |
|||
margin-bottom: $h1-margin-bottom; |
|||
border: 2px solid $print-color-light; |
|||
border-width: 2px 0; |
|||
text-align: center; |
|||
} |
|||
|
|||
h2 { |
|||
@extend %header-font; |
|||
font-size: 1.8em; |
|||
margin-top: 2em; |
|||
border-top: 2px solid $print-color-light; |
|||
padding-top: 0.8em; |
|||
} |
|||
|
|||
h1+h2, h1+div+h2 { |
|||
border-top: none; |
|||
padding-top: 0; |
|||
margin-top: 0; |
|||
} |
|||
|
|||
h3, h4 { |
|||
@extend %header-font; |
|||
font-size: 0.8em; |
|||
margin-top: 1.5em; |
|||
margin-bottom: 0.8em; |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
h5, h6 { |
|||
text-transform: uppercase; |
|||
} |
|||
|
|||
aside { |
|||
padding: 1em; |
|||
border: 1px solid $print-color-light; |
|||
border-radius: 5px; |
|||
margin-top: 1.5em; |
|||
margin-bottom: 1.5em; |
|||
line-height: 1.6; |
|||
} |
|||
|
|||
aside:before { |
|||
vertical-align: middle; |
|||
padding-right: 0.5em; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
aside.notice:before { |
|||
@extend %icon-info-sign; |
|||
} |
|||
|
|||
aside.warning:before { |
|||
@extend %icon-exclamation-sign; |
|||
} |
|||
|
|||
aside.success:before { |
|||
@extend %icon-ok-sign; |
|||
} |
|||
} |
@ -0,0 +1,616 @@ |
|||
@charset "utf-8"; |
|||
@import 'normalize'; |
|||
@import 'variables'; |
|||
@import 'icon-font'; |
|||
|
|||
/* |
|||
Copyright 2008-2013 Concur Technologies, Inc. |
|||
|
|||
Licensed under the Apache License, Version 2.0 (the "License"); you may |
|||
not use this file except in compliance with the License. You may obtain |
|||
a copy of the License at |
|||
|
|||
http://www.apache.org/licenses/LICENSE-2.0 |
|||
|
|||
Unless required by applicable law or agreed to in writing, software |
|||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
|||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
|||
License for the specific language governing permissions and limitations |
|||
under the License. |
|||
*/ |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// GENERAL STUFF |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
html, body { |
|||
color: $main-text; |
|||
padding: 0; |
|||
margin: 0; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
@extend %default-font; |
|||
background-color: $main-bg; |
|||
height: 100%; |
|||
-webkit-text-size-adjust: none; /* Never autoresize text */ |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// TABLE OF CONTENTS |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#toc > ul > li > a > span { |
|||
float: right; |
|||
background-color: #2484FF; |
|||
border-radius: 40px; |
|||
width: 20px; |
|||
} |
|||
|
|||
.toc-wrapper { |
|||
transition: left 0.3s ease-in-out; |
|||
|
|||
overflow-y: auto; |
|||
overflow-x: hidden; |
|||
position: fixed; |
|||
z-index: 30; |
|||
top: 0; |
|||
left: 0; |
|||
bottom: 0; |
|||
width: $nav-width; |
|||
background-color: $nav-bg; |
|||
font-size: 13px; |
|||
font-weight: bold; |
|||
|
|||
// language selector for mobile devices |
|||
.lang-selector { |
|||
display: none; |
|||
a { |
|||
padding-top: 0.5em; |
|||
padding-bottom: 0.5em; |
|||
} |
|||
} |
|||
|
|||
// This is the logo at the top of the ToC |
|||
&>img { |
|||
display: block; |
|||
max-width: 100%; |
|||
} |
|||
|
|||
&>.search { |
|||
position: relative; |
|||
|
|||
input { |
|||
background: $nav-bg; |
|||
border-width: 0 0 1px 0; |
|||
border-color: $search-box-border-color; |
|||
padding: 6px 0 6px 20px; |
|||
box-sizing: border-box; |
|||
margin: $nav-v-padding $nav-padding; |
|||
width: $nav-width - 30; |
|||
outline: none; |
|||
color: $nav-text; |
|||
border-radius: 0; /* ios has a default border radius */ |
|||
} |
|||
|
|||
&:before { |
|||
position: absolute; |
|||
top: 17px; |
|||
left: $nav-padding; |
|||
color: $nav-text; |
|||
@extend %icon-search; |
|||
} |
|||
} |
|||
|
|||
.logo { |
|||
margin-bottom: $logo-margin; |
|||
} |
|||
|
|||
.search-results { |
|||
margin-top: 0; |
|||
box-sizing: border-box; |
|||
height: 0; |
|||
overflow-y: auto; |
|||
overflow-x: hidden; |
|||
transition-property: height, margin; |
|||
transition-duration: 180ms; |
|||
transition-timing-function: ease-in-out; |
|||
background: $nav-subitem-bg; |
|||
&.visible { |
|||
height: 30%; |
|||
margin-bottom: 1em; |
|||
} |
|||
|
|||
li { |
|||
margin: 1em $nav-padding; |
|||
line-height: 1; |
|||
} |
|||
|
|||
a { |
|||
color: $nav-text; |
|||
text-decoration: none; |
|||
|
|||
&:hover { |
|||
text-decoration: underline; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
// The Table of Contents is composed of multiple nested |
|||
// unordered lists. These styles remove the default |
|||
// styling of an unordered list because it is ugly. |
|||
ul, li { |
|||
list-style: none; |
|||
margin: 0; |
|||
padding: 0; |
|||
line-height: 28px; |
|||
} |
|||
|
|||
li { |
|||
color: $nav-text; |
|||
transition-property: background; |
|||
transition-timing-function: linear; |
|||
transition-duration: 200ms; |
|||
} |
|||
|
|||
// This is the currently selected ToC entry |
|||
.toc-link.active { |
|||
background-color: $nav-active-bg; |
|||
color: $nav-active-text; |
|||
} |
|||
|
|||
// this is parent links of the currently selected ToC entry |
|||
.toc-link.active-parent { |
|||
background-color: $nav-active-parent-bg; |
|||
color: $nav-active-parent-text; |
|||
} |
|||
|
|||
.toc-list-h2 { |
|||
display: none; |
|||
background-color: $nav-subitem-bg; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.toc-h2 { |
|||
padding-left: $nav-padding + $nav-indent; |
|||
font-size: 12px; |
|||
} |
|||
|
|||
.toc-footer { |
|||
padding: 1em 0; |
|||
margin-top: 1em; |
|||
border-top: 1px dashed $nav-footer-border-color; |
|||
|
|||
li,a { |
|||
color: $nav-text; |
|||
text-decoration: none; |
|||
} |
|||
|
|||
a:hover { |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
li { |
|||
font-size: 0.8em; |
|||
line-height: 1.7; |
|||
text-decoration: none; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.toc-link, .toc-footer li { |
|||
padding: 0 $nav-padding 0 $nav-padding; |
|||
display: block; |
|||
overflow-x: hidden; |
|||
white-space: nowrap; |
|||
text-overflow: ellipsis; |
|||
text-decoration: none; |
|||
color: #fff; |
|||
transition-property: background; |
|||
transition-timing-function: linear; |
|||
transition-duration: 130ms; |
|||
} |
|||
|
|||
// button to show navigation on mobile devices |
|||
#nav-button { |
|||
span { |
|||
display: block; |
|||
$side-pad: $main-padding / 2 - 8px; |
|||
padding: $side-pad $side-pad $side-pad; |
|||
background-color: rgba($main-bg, 0.7); |
|||
transform-origin: 0 0; |
|||
transform: rotate(-90deg) translate(-100%, 0); |
|||
border-radius: 0 0 0 5px; |
|||
} |
|||
padding: 0 1.5em 5em 0; // increase touch size area |
|||
display: none; |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 100; |
|||
color: #000; |
|||
text-decoration: none; |
|||
font-weight: bold; |
|||
opacity: 0.7; |
|||
line-height: 16px; |
|||
img { |
|||
height: 16px; |
|||
vertical-align: bottom; |
|||
} |
|||
|
|||
transition: left 0.3s ease-in-out; |
|||
|
|||
&:hover { opacity: 1; } |
|||
&.open {left: $nav-width} |
|||
} |
|||
|
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// PAGE LAYOUT AND CODE SAMPLE BACKGROUND |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
|
|||
.page-wrapper { |
|||
margin-left: $nav-width; |
|||
position: relative; |
|||
z-index: 10; |
|||
background-color: $main-bg; |
|||
min-height: 100%; |
|||
|
|||
padding-bottom: 1px; // prevent margin overflow |
|||
|
|||
// The dark box is what gives the code samples their dark background. |
|||
// It sits essentially under the actual content block, which has a |
|||
// transparent background. |
|||
// I know, it's hackish, but it's the simplist way to make the left |
|||
// half of the content always this background color. |
|||
.dark-box { |
|||
width: $examples-width; |
|||
background-color: $examples-bg; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
bottom: 0; |
|||
} |
|||
|
|||
.lang-selector { |
|||
position: fixed; |
|||
z-index: 50; |
|||
border-bottom: 5px solid $lang-select-active-bg; |
|||
} |
|||
} |
|||
|
|||
.lang-selector { |
|||
background-color: $lang-select-bg; |
|||
width: 100%; |
|||
font-weight: bold; |
|||
a { |
|||
display: block; |
|||
float:left; |
|||
color: $lang-select-text; |
|||
text-decoration: none; |
|||
padding: 0 10px; |
|||
line-height: 30px; |
|||
outline: 0; |
|||
|
|||
&:active, &:focus { |
|||
background-color: $lang-select-pressed-bg; |
|||
color: $lang-select-pressed-text; |
|||
} |
|||
|
|||
&.active { |
|||
background-color: $lang-select-active-bg; |
|||
color: $lang-select-active-text; |
|||
} |
|||
} |
|||
|
|||
&:after { |
|||
content: ''; |
|||
clear: both; |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// CONTENT STYLES |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// This is all the stuff with the light background in the left half of the page |
|||
|
|||
.content { |
|||
// fixes webkit rendering bug for some: see #538 |
|||
-webkit-transform: translateZ(0); |
|||
// to place content above the dark box |
|||
position: relative; |
|||
z-index: 30; |
|||
|
|||
&:after { |
|||
content: ''; |
|||
display: block; |
|||
clear: both; |
|||
} |
|||
|
|||
&>h1, &>h2, &>h3, &>h4, &>h5, &>h6, &>p, &>table, &>ul, &>ol, &>aside, &>dl { |
|||
margin-right: $examples-width; |
|||
padding: 0 $main-padding; |
|||
box-sizing: border-box; |
|||
display: block; |
|||
|
|||
@extend %left-col; |
|||
} |
|||
|
|||
&>ul, &>ol { |
|||
padding-left: $main-padding + 15px; |
|||
} |
|||
|
|||
// the div is the tocify hidden div for placeholding stuff |
|||
&>h1, &>h2, &>div { |
|||
clear:both; |
|||
} |
|||
|
|||
h1 { |
|||
@extend %header-font; |
|||
font-size: 25px; |
|||
padding-top: 0.5em; |
|||
padding-bottom: 0.5em; |
|||
margin-bottom: $h1-margin-bottom; |
|||
margin-top: 2em; |
|||
border-top: 1px solid #ccc; |
|||
border-bottom: 1px solid #ccc; |
|||
background-color: #fdfdfd; |
|||
} |
|||
|
|||
h1:first-child, div:first-child + h1 { |
|||
border-top-width: 0; |
|||
margin-top: 0; |
|||
} |
|||
|
|||
h2 { |
|||
@extend %header-font; |
|||
font-size: 19px; |
|||
margin-top: 4em; |
|||
margin-bottom: 0; |
|||
border-top: 1px solid #ccc; |
|||
padding-top: 1.2em; |
|||
padding-bottom: 1.2em; |
|||
background-image: linear-gradient(to bottom, rgba(#fff, 0.2), rgba(#fff, 0)); |
|||
} |
|||
|
|||
// h2s right after h1s should bump right up |
|||
// against the h1s. |
|||
h1 + h2, h1 + div + h2 { |
|||
margin-top: $h1-margin-bottom * -1; |
|||
border-top: none; |
|||
} |
|||
|
|||
h3, h4, h5, h6 { |
|||
@extend %header-font; |
|||
font-size: 15px; |
|||
margin-top: 2.5em; |
|||
margin-bottom: 0.8em; |
|||
} |
|||
|
|||
h4, h5, h6 { |
|||
font-size: 10px; |
|||
} |
|||
|
|||
hr { |
|||
margin: 2em 0; |
|||
border-top: 2px solid $examples-bg; |
|||
border-bottom: 2px solid $main-bg; |
|||
} |
|||
|
|||
table { |
|||
margin-bottom: 1em; |
|||
overflow: auto; |
|||
th,td { |
|||
text-align: left; |
|||
vertical-align: top; |
|||
line-height: 1.6; |
|||
} |
|||
|
|||
th { |
|||
padding: 5px 10px; |
|||
border-bottom: 1px solid #ccc; |
|||
vertical-align: bottom; |
|||
} |
|||
|
|||
td { |
|||
padding: 10px; |
|||
} |
|||
|
|||
tr:last-child { |
|||
border-bottom: 1px solid #ccc; |
|||
} |
|||
|
|||
tr:nth-child(odd)>td { |
|||
background-color: lighten($main-bg,4.2%); |
|||
} |
|||
|
|||
tr:nth-child(even)>td { |
|||
background-color: lighten($main-bg,2.4%); |
|||
} |
|||
} |
|||
|
|||
dt { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
dd { |
|||
margin-left: 15px; |
|||
} |
|||
|
|||
p, li, dt, dd { |
|||
line-height: 1.6; |
|||
margin-top: 0; |
|||
} |
|||
|
|||
img { |
|||
max-width: 100%; |
|||
} |
|||
|
|||
code { |
|||
background-color: rgba(0,0,0,0.05); |
|||
padding: 3px; |
|||
border-radius: 3px; |
|||
@extend %break-words; |
|||
@extend %code-font; |
|||
} |
|||
|
|||
pre>code { |
|||
background-color: transparent; |
|||
padding: 0; |
|||
} |
|||
|
|||
aside { |
|||
padding-top: 1em; |
|||
padding-bottom: 1em; |
|||
margin-top: 1.5em; |
|||
margin-bottom: 1.5em; |
|||
background: $aside-notice-bg; |
|||
line-height: 1.6; |
|||
|
|||
&.warning { |
|||
background-color: $aside-warning-bg; |
|||
} |
|||
|
|||
&.success { |
|||
background-color: $aside-success-bg; |
|||
} |
|||
} |
|||
|
|||
aside:before { |
|||
vertical-align: middle; |
|||
padding-right: 0.5em; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
aside.notice:before { |
|||
@extend %icon-info-sign; |
|||
} |
|||
|
|||
aside.warning:before { |
|||
@extend %icon-exclamation-sign; |
|||
} |
|||
|
|||
aside.success:before { |
|||
@extend %icon-ok-sign; |
|||
} |
|||
|
|||
.search-highlight { |
|||
padding: 2px; |
|||
margin: -2px; |
|||
border-radius: 4px; |
|||
border: 1px solid #F7E633; |
|||
background: linear-gradient(to top left, #F7E633 0%, #F1D32F 100%); |
|||
} |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// CODE SAMPLE STYLES |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// This is all the stuff that appears in the right half of the page |
|||
|
|||
.content { |
|||
pre, blockquote { |
|||
background-color: $code-bg; |
|||
color: #fff; |
|||
|
|||
margin: 0; |
|||
width: $examples-width; |
|||
|
|||
float:right; |
|||
clear:right; |
|||
|
|||
box-sizing: border-box; |
|||
|
|||
@extend %right-col; |
|||
|
|||
&>p { margin: 0; } |
|||
|
|||
a { |
|||
color: #fff; |
|||
text-decoration: none; |
|||
border-bottom: dashed 1px #ccc; |
|||
} |
|||
} |
|||
|
|||
pre { |
|||
@extend %code-font; |
|||
padding-top: 2em; |
|||
padding-bottom: 2em; |
|||
padding: 2em $main-padding; |
|||
} |
|||
|
|||
blockquote { |
|||
&>p { |
|||
background-color: $code-annotation-bg; |
|||
padding: $code-annotation-padding 2em; |
|||
color: #eee; |
|||
} |
|||
} |
|||
} |
|||
|
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// RESPONSIVE DESIGN |
|||
//////////////////////////////////////////////////////////////////////////////// |
|||
// These are the styles for phones and tablets |
|||
// There are also a couple styles disperesed |
|||
|
|||
@media (max-width: $tablet-width) { |
|||
.toc-wrapper { |
|||
left: -$nav-width; |
|||
|
|||
&.open { |
|||
left: 0; |
|||
} |
|||
} |
|||
|
|||
.page-wrapper { |
|||
margin-left: 0; |
|||
} |
|||
|
|||
#nav-button { |
|||
display: block; |
|||
} |
|||
|
|||
.toc-link { |
|||
padding-top: 0.3em; |
|||
padding-bottom: 0.3em; |
|||
} |
|||
} |
|||
|
|||
@media (max-width: $phone-width) { |
|||
.dark-box { |
|||
display: none; |
|||
} |
|||
|
|||
%left-col { |
|||
margin-right: 0; |
|||
} |
|||
|
|||
.toc-wrapper .lang-selector { |
|||
display: block; |
|||
} |
|||
|
|||
.page-wrapper .lang-selector { |
|||
display: none; |
|||
} |
|||
|
|||
%right-col { |
|||
width: auto; |
|||
float: none; |
|||
} |
|||
|
|||
%right-col + %left-col { |
|||
margin-top: $main-padding; |
|||
} |
|||
} |
|||
|
|||
.highlight .c, .highlight .cm, .highlight .c1, .highlight .cs { |
|||
color: #909090; |
|||
} |
|||
|
|||
.highlight, .highlight .w { |
|||
background-color: $code-bg; |
|||
} |
|||
|
|||
@import 'custom'; |
@ -0,0 +1,6 @@ |
|||
#!/bin/sh |
|||
cd ./api-docs-slate |
|||
gem install bundler |
|||
bundle install |
|||
bundle exec middleman build --clean # build api docs |
|||
cp -RT ./build/ ../api-docs && rm -r ./build |
@ -0,0 +1,699 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|||
<meta name="description" content=""> |
|||
<meta name="author" content=""> |
|||
|
|||
<title>bcoin | Extending Bitcoin into Enterprise & Production</title> |
|||
|
|||
<!-- Favicons --> |
|||
<!-- old |
|||
<link rel="shortcut icon" href="../assets/images/bcoin-ico.png">--> |
|||
|
|||
<!-- generated from http://www.favicon-generator.org/ --> |
|||
<link rel="apple-touch-icon" sizes="57x57" href="../assets/images/apple-icon-57x57.png"> |
|||
<link rel="apple-touch-icon" sizes="60x60" href="../assets/images/apple-icon-60x60.png"> |
|||
<link rel="apple-touch-icon" sizes="72x72" href="../assets/images/apple-icon-72x72.png"> |
|||
<link rel="apple-touch-icon" sizes="76x76" href="../assets/images/apple-icon-76x76.png"> |
|||
<link rel="apple-touch-icon" sizes="114x114" href="../assets/images/apple-icon-114x114.png"> |
|||
<link rel="apple-touch-icon" sizes="120x120" href="../assets/images/apple-icon-120x120.png"> |
|||
<link rel="apple-touch-icon" sizes="144x144" href="../assets/images/apple-icon-144x144.png"> |
|||
<link rel="apple-touch-icon" sizes="152x152" href="../assets/images/apple-icon-152x152.png"> |
|||
<link rel="apple-touch-icon" sizes="180x180" href="../assets/images/apple-icon-180x180.png"> |
|||
<link rel="icon" type="image/png" sizes="192x192" href="../assets/images/android-icon-192x192.png"> |
|||
<link rel="icon" type="image/png" sizes="32x32" href="../assets/images/favicon-32x32.png"> |
|||
<link rel="icon" type="image/png" sizes="96x96" href="../assets/images/favicon-96x96.png"> |
|||
<link rel="icon" type="image/png" sizes="16x16" href="../assets/images/favicon-16x16.png"> |
|||
<link rel="manifest" href="../assets/images/manifest.json"> |
|||
<meta name="msapplication-TileColor" content="#ffffff"> |
|||
<meta name="msapplication-TileImage" content="../assets/images/ms-icon-144x144.png"> |
|||
<meta name="theme-color" content="#ffffff"> |
|||
|
|||
<!-- Web Fonts --> |
|||
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400italic,400,600,700' rel='stylesheet'> |
|||
<link href='https://fonts.googleapis.com/css?family=Montserrat:700' rel='stylesheet' type='text/css'> |
|||
|
|||
<!-- Bootstrap core CSS --> |
|||
<link href="../assets/bootstrap/css/bootstrap.min.css" rel="stylesheet"> |
|||
|
|||
<!-- Code Snippet CSS --> |
|||
<link href="../assets/css/prism.css" rel="stylesheet"> |
|||
|
|||
<link href="../assets/css/custom.css" rel="stylesheet"> |
|||
|
|||
<!-- Icon Fonts --> |
|||
<link href="../assets/css/font-awesome.min.css" rel="stylesheet"> |
|||
<link href="../assets/css/simple-line-icons.css" rel="stylesheet"> |
|||
|
|||
<!-- Plugins --> |
|||
<link href="../assets/css/magnific-popup.css" rel="stylesheet"> |
|||
<link href="../assets/css/owl.carousel.css" rel="stylesheet"> |
|||
<link href="../assets/css/flexslider.css" rel="stylesheet"> |
|||
<link href="../assets/css/animate.min.css" rel="stylesheet"> |
|||
|
|||
<!-- Template core CSS --> |
|||
<link href="../assets/css/vertical.min.css" rel="stylesheet"> |
|||
<link href="../assets/css/template.css" rel="stylesheet"> |
|||
|
|||
<!-- Google Analytics Tracking --> |
|||
<script> |
|||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ |
|||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), |
|||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) |
|||
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); |
|||
ga('create', 'UA-96446060-1', 'auto'); |
|||
ga('send', 'pageview'); |
|||
</script> |
|||
</head> |
|||
<body> |
|||
|
|||
<!-- PRELOADER --> |
|||
<div class="page-loader"> |
|||
<div class="img-loader">Loading... |
|||
<!-- Bcoin logo in SVG --> |
|||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |
|||
viewBox="0 0 200 56" style="enable-background:new 0 0 200 56;" xml:space="preserve"> |
|||
<g id="XMLID_108_"> |
|||
<g id="XMLID_123_"> |
|||
<path id="XMLID_124_" d="M8.4,51.8H3.2V4.2h5.2v19.2h0.8c1.2-2,2.8-3.6,4.8-4.7c2-1.1,4.3-1.6,6.7-1.6c2,0,4,0.4,5.8,1.2 |
|||
c1.8,0.8,3.4,1.9,4.8,3.3c1.4,1.5,2.5,3.2,3.3,5.4s1.2,4.6,1.2,7.3v1.4c0,2.8-0.4,5.2-1.2,7.4c-0.8,2.1-1.9,3.9-3.3,5.4 |
|||
c-1.4,1.5-3,2.6-4.9,3.3s-3.8,1.1-5.9,1.1c-1.1,0-2.2-0.1-3.3-0.4c-1.1-0.3-2.2-0.6-3.2-1.2c-1-0.5-1.9-1.2-2.8-1.9 |
|||
c-0.8-0.7-1.6-1.6-2.1-2.7H8.4V51.8z M19.4,47.7c1.6,0,3.1-0.3,4.4-0.9c1.3-0.6,2.5-1.4,3.5-2.4c1-1,1.8-2.3,2.3-3.8 |
|||
c0.6-1.5,0.8-3.2,0.8-5v-1.4c0-1.8-0.3-3.5-0.8-4.9c-0.6-1.5-1.3-2.7-2.3-3.8c-1-1.1-2.2-1.9-3.5-2.5c-1.4-0.6-2.8-0.9-4.4-0.9 |
|||
c-1.6,0-3,0.3-4.3,0.9c-1.3,0.6-2.5,1.5-3.5,2.6c-1,1.1-1.8,2.4-2.4,3.9c-0.6,1.5-0.9,3.2-0.9,5v0.8c0,1.9,0.3,3.6,0.9,5.1 |
|||
c0.6,1.5,1.4,2.8,2.4,3.9s2.2,1.9,3.5,2.5C16.4,47.4,17.9,47.7,19.4,47.7z"/> |
|||
</g> |
|||
<g id="XMLID_120_"> |
|||
<path id="XMLID_121_" d="M76.1,39.8c-0.4,1.9-1,3.6-1.8,5.2c-0.9,1.6-2,3-3.3,4.1s-2.9,2.1-4.7,2.7c-1.8,0.6-3.8,1-5.9,1 |
|||
c-2.3,0-4.5-0.4-6.6-1.2c-2.1-0.8-3.9-1.9-5.4-3.4c-1.6-1.5-2.8-3.3-3.7-5.4c-0.9-2.1-1.4-4.6-1.4-7.4v-0.8c0-2.7,0.5-5.2,1.4-7.4 |
|||
c0.9-2.2,2.1-4,3.7-5.5c1.6-1.5,3.4-2.7,5.4-3.5c2.1-0.8,4.3-1.2,6.6-1.2c2.1,0,4,0.3,5.8,1c1.8,0.6,3.3,1.5,4.7,2.7 |
|||
c1.4,1.2,2.5,2.5,3.3,4.1c0.9,1.6,1.5,3.3,1.8,5.2l-5.2,1.2c-0.1-1.2-0.5-2.3-1-3.4c-0.5-1.1-1.2-2.1-2.1-2.9 |
|||
c-0.9-0.8-1.9-1.5-3.2-2c-1.2-0.5-2.7-0.7-4.3-0.7c-1.6,0-3.1,0.3-4.5,0.9c-1.4,0.6-2.6,1.5-3.7,2.6c-1.1,1.1-1.9,2.4-2.5,4 |
|||
c-0.6,1.5-0.9,3.2-0.9,5v0.8c0,1.9,0.3,3.6,0.9,5.1c0.6,1.5,1.4,2.8,2.5,3.8c1.1,1,2.3,1.8,3.7,2.4c1.4,0.6,3,0.9,4.6,0.9 |
|||
s3.1-0.3,4.3-0.8c1.2-0.5,2.3-1.2,3.1-2c0.9-0.8,1.6-1.8,2.1-2.9c0.5-1.1,0.9-2.2,1-3.4L76.1,39.8z"/> |
|||
</g> |
|||
<g id="XMLID_116_"> |
|||
<path id="XMLID_117_" d="M117.2,35.4c0,2.8-0.5,5.3-1.4,7.5c-0.9,2.2-2.1,4-3.6,5.4c-1.5,1.5-3.3,2.6-5.3,3.4 |
|||
c-2,0.8-4.1,1.2-6.3,1.2c-2.2,0-4.3-0.4-6.3-1.2c-2-0.8-3.8-1.9-5.3-3.4c-1.5-1.5-2.7-3.3-3.6-5.4c-0.9-2.2-1.4-4.6-1.4-7.5v-0.8 |
|||
c0-2.8,0.5-5.2,1.4-7.4c0.9-2.2,2.1-4,3.7-5.5c1.5-1.5,3.3-2.6,5.3-3.4c2-0.8,4.1-1.2,6.3-1.2c2.2,0,4.3,0.4,6.3,1.2 |
|||
c2,0.8,3.8,1.9,5.3,3.4c1.5,1.5,2.8,3.3,3.7,5.5c0.9,2.2,1.4,4.6,1.4,7.4V35.4z M100.6,47.7c1.6,0,3.1-0.3,4.4-0.9 |
|||
c1.4-0.6,2.5-1.4,3.6-2.5c1-1.1,1.8-2.4,2.4-3.9c0.6-1.5,0.9-3.2,0.9-5.1v-0.8c0-1.8-0.3-3.5-0.9-5c-0.6-1.5-1.4-2.8-2.4-3.9 |
|||
c-1-1.1-2.2-1.9-3.6-2.6c-1.4-0.6-2.8-0.9-4.4-0.9c-1.6,0-3,0.3-4.4,0.9c-1.4,0.6-2.6,1.5-3.6,2.6c-1,1.1-1.8,2.4-2.4,3.9 |
|||
c-0.6,1.5-0.9,3.2-0.9,5v0.8c0,1.9,0.3,3.6,0.9,5.1c0.6,1.5,1.4,2.8,2.4,3.9c1,1.1,2.2,1.9,3.6,2.5C97.5,47.5,99,47.7,100.6,47.7z |
|||
"/> |
|||
</g> |
|||
<g id="XMLID_112_"> |
|||
<path id="XMLID_113_" d="M127.6,46.9h11.6V23h-10.4v-4.9h15.6v28.9h10.8v4.9h-27.6V46.9z M137.1,8c0-1.3,0.5-2.4,1.4-3.4 |
|||
c0.9-0.9,2-1.4,3.3-1.4c1.3,0,2.4,0.5,3.3,1.4c0.9,0.9,1.4,2.1,1.4,3.4c0,1.3-0.5,2.4-1.4,3.4c-0.9,0.9-2,1.4-3.3,1.4 |
|||
c-1.3,0-2.4-0.5-3.3-1.4C137.5,10.4,137.1,9.3,137.1,8z"/> |
|||
</g> |
|||
<g id="XMLID_109_"> |
|||
<path id="XMLID_110_" d="M172.8,51.8h-5.2V18.1h5.2v5.7h0.8c2-4.4,5.6-6.7,10.7-6.7c3.8,0,6.9,1.2,9.1,3.6 |
|||
c2.3,2.4,3.4,6.1,3.4,10.9v20.2h-5.2V32.8c0-3.5-0.8-6.2-2.3-8c-1.6-1.8-3.7-2.7-6.3-2.7c-3.2,0-5.6,1.1-7.4,3.3s-2.7,5.1-2.7,8.8 |
|||
V51.8z"/> |
|||
</g> |
|||
</g> |
|||
</svg> |
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
<!-- END PRELOADER --> |
|||
|
|||
<!-- HEADER --> |
|||
<header class="header js-stick"> |
|||
<div class="container"> |
|||
<!-- YOUR LOGO HERE --> |
|||
<div class="inner-header"> |
|||
<a class="inner-brand" href="../index.html"> |
|||
<img class="brand-light" src="../assets/images/logo-light.png" width="100" alt=""> |
|||
<img class="brand-dark" src="../assets/images/logo-dark.png" width="100" alt=""> |
|||
</a> |
|||
</div> |
|||
|
|||
<!-- OPEN MOBILE MENU --> |
|||
<div class="main-nav-toggle"> |
|||
<div class="nav-icon-toggle" data-toggle="collapse" data-target="#custom-collapse"> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
<span class="icon-bar"></span> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- WIDGETS MENU --> |
|||
<div class="inner-header pull-right hide-me"> |
|||
<div class="menu-extras clearfix"> |
|||
|
|||
<!-- SLACK LINK --> |
|||
<div class="menu-item"> |
|||
<div class=""> |
|||
<a href="../slack-signup.html" target="_blank" id="" data-toggle="tooltip" title="" data-placement="bottom" data-original-title="Join us on Slack!"> |
|||
<img src="../assets/images/slack_icon.svg" width="18" height="18"/> |
|||
<span class=""></span> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- STACK EXCHANGE LINK --> |
|||
<div class="menu-item"> |
|||
<div class=""> |
|||
<a href="https://bitcoin.stackexchange.com/questions/tagged/bcoin" target="_blank" id="" data-toggle="tooltip" title="" data-placement="bottom" data-original-title="Questions! Checkout Stack Exchange."> |
|||
<img src="../assets/images/stack-exchange-icon.svg" width="18" height="18"/> |
|||
<span class=""></span> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- GITHUB STUFF --> |
|||
<div class="menu-item"> |
|||
<div class=""> |
|||
<a href="https://github.com/bcoin-org/bcoin" target="_blank" id="" data-toggle="tooltip" title="" data-placement="bottom" data-original-title="Visit bcoin on GitHub to see the code!"> |
|||
<img src="../assets/images/github_icon.svg" width="18" height="18"/> |
|||
<span class=""></span> |
|||
</a> |
|||
</div> |
|||
</div> |
|||
|
|||
<div class="menu-item"> |
|||
<div class="ghbuttons"> |
|||
<a class="github-button" href="https://github.com/bcoin-org/bcoin" data-icon="octicon-star" data-count-href="/bcoin-org/bcoin/stargazers" data-show-count="true" data-count-aria-label="# stargazers on GitHub" aria-label="Star bcoin-org/bcoin on GitHub">Star</a> |
|||
<a class="github-button" href="https://github.com/bcoin-org/bcoin/fork" data-icon="octicon-repo-forked" data-count-href="/bcoin-org/bcoin/network" data-show-count="true" data-count-aria-label="# forks on GitHub" aria-label="Fork bcoin-org/bcoin on GitHub">Fork</a> |
|||
</div> |
|||
</div> |
|||
|
|||
|
|||
|
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
<!-- MAIN MENU --> |
|||
<nav id="custom-collapse" class="main-nav collapse clearfix"> |
|||
<ul class="inner-nav pull-right"> |
|||
|
|||
<!-- HOME --> |
|||
<li><a href="../index.html">Home</a></li> |
|||
<!-- END HOME --> |
|||
|
|||
<!-- FEATURES --> |
|||
<li><a href="../index.html#features">What is Bcoin</a></li> |
|||
<!-- END FEATURES --> |
|||
|
|||
<!-- GUIDES --> |
|||
<li><a href="../guides.html">Guides</a></li> |
|||
<!-- GUIDES --> |
|||
|
|||
<!-- API REFERENCE - newer, how to interact once you're setup --> |
|||
<li><a href="../api-docs/index.html">API Docs</a></li> |
|||
<!-- END API --> |
|||
|
|||
<!-- FULL DOCS - older, full reference |
|||
<li><a href="http://bcoin.io/docs/index.html">Docs</a></li> --> |
|||
<!-- END DOCS --> |
|||
|
|||
<!-- DIVIDER |
|||
<li><a> </a></li> |
|||
|
|||
<li><a href="#">All Demos</a></li>--> |
|||
|
|||
</ul> |
|||
</nav> |
|||
|
|||
</div> |
|||
</header> |
|||
<!-- END HEADER --> |
|||
|
|||
<!-- WRAPPER --> |
|||
<div class="wrapper"> |
|||
|
|||
<!-- PAGE TITLE --> |
|||
<section class="module-sm bg-white-dark" data-background="../assets/images/bg-header.jpg"> |
|||
<div class="container"> |
|||
|
|||
<div class="row"> |
|||
<div class="col-sm-12 text-center"> |
|||
|
|||
<h2 class="montserrat text-uppercase m-b-10"><span class="text-highlight-black" style="line-height: 1.5;"> Guides and Videos </span></h2> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</section> |
|||
<!-- END PAGE TITLE --> |
|||
|
|||
<!-- GUIDES/TUTORIALS --> |
|||
<section class="module" style="padding-top:70px !important;"> |
|||
<div class="container"> |
|||
|
|||
<div class="row"> |
|||
|
|||
<!-- START SIDEBAR --> |
|||
<div class="col-sm-3 sidebar"> |
|||
<!-- CATEGORIES WIDGET --> |
|||
<div class="widget guide-list"> |
|||
<h6 class="montserrat text-uppercase bottom-line">Install</h6> |
|||
<ul class="icons-list"> |
|||
<!-- INSTALL-LIST --> |
|||
<li><a href="install-windows.html">Install on Windows (Video)</a></li> |
|||
<li><a href="install-mac.html">Install on Mac OS (Video)</a></li> |
|||
<li><a href="install-linux.html">Install on Linux (Video)</a></li> |
|||
<!-- /INSTALL-LIST --> |
|||
</ul> |
|||
<br> |
|||
<h6 class="montserrat text-uppercase bottom-line">Guides</h6> |
|||
<ul class="icons-list"> |
|||
<!-- GUIDES-LIST --> |
|||
<li><a href="working-with-txs.html">Working with transactions</a></li> |
|||
<li><a href="wallets.html">Wallets and Accounts and Keys, Oh My!</a></li> |
|||
<li><a href="scripting.html">Intro to Scripting</a></li> |
|||
<li><a href="op_return.html">Store Data on the Blockchain</a></li> |
|||
<li><a href="multisig-tx.html">Creating Multisignature Transactions</a></li> |
|||
<li><a href="generate-address.html">Generate an Address</a></li> |
|||
<li><a href="crowdfund-tx.html">Create a Crowdfunding Transaction</a></li> |
|||
<!-- /GUIDES-LIST --> |
|||
</ul> |
|||
</div> |
|||
<!-- END CATEGORIES WIDGET --> |
|||
|
|||
<!-- TEXT WIDGET --> |
|||
<div class="widget"> |
|||
<h6 class="montserrat text-uppercase bottom-line">Looking for Docs?</h6> |
|||
<p>Checkout our <a href="../api-docs/index.html">API Docs</a> or the <a href="http://bcoin.io/docs/index.html">Full Documentation</a></p> |
|||
</div> |
|||
<!-- END TEXT WIDGET --> |
|||
|
|||
<!-- TEXT WIDGET --> |
|||
<div class="widget"> |
|||
<h6 class="montserrat text-uppercase bottom-line">Get Involved</h6> |
|||
<p>If you think you've got what it takes to make your own bcoin guides and tutorials, head on over to our <a href="https://github.com/bcoin-org/bcoin-org.github.io">GitHub repo</a> to see how you can make a request or contribute your own and earn bounties! You can also reach out to us on <a href="../slack-signup.html"> Slack.</a></p> |
|||
<p>Want to join the team?<a href="https://angel.co/purse/jobs/90956-bitcoin-protocol-engineer-bcoin"> We’re hiring.</a></p> |
|||
</div> |
|||
<!-- END TEXT WIDGET --> |
|||
</div> |
|||
<!-- END SIDEBAR --> |
|||
<!-- START OF ARTICLE CONTAINER --> |
|||
<div class="col-sm-9 blog-content post-thumbnail"> |
|||
<!-- POST IMAGE --> |
|||
<article class="post format-image"> |
|||
<div class="row"> |
|||
<!--<div class="col-sm-5"> |
|||
<div class="post-preview"> |
|||
<a href="#"><img src="../assets/images/guides/get-started.png" alt=""></a> |
|||
</div> |
|||
</div>--> |
|||
|
|||
<!-- after re-enabling the above code, change the col-sm below to col-sm-7 --> |
|||
<div class="panel-group"> |
|||
<div class="col-sm-12 panel panel-default"> |
|||
<div class="post-content" style="color:#000;"> |
|||
<!-- START OF GUIDE --> |
|||
<h2 class="post-title panel-title" id="wallets-and-accounts-and-keys-oh-my!">Wallets and Accounts and Keys, Oh My!</h2><ul class="post-meta"><li class="author">By Daniel McNally</li></ul><p>Bcoin offers a powerful, modular way to create and manage bitcoin wallets. In this guide, I'll walk you through the concepts and features you'll need to know about to get started.</p> |
|||
<h2 id="the-basics">The Basics</h2><p>If you're a seasoned bitcoiner, you can probably skim this section or skip straight ahead to the <a href="#examples">Examples</a> section. But if you're relatively new or just want a refresher, this section will help you understand how wallets actually work. </p> |
|||
<h3 id="wallets">Wallets</h3><p>In the most basic sense, a bitcoin wallet is data that enables you to receive and spend bitcoins. Wallets come in <a href="https://www.coindesk.com/information/how-to-store-your-bitcoins/">many different types and designs</a>, and assessing all the options can be overwhelming. Fortunately, bcoin implements the latest specifications for structuring wallets that are easy to backup, easy to restore, and that work just as well for a bitcoin novice making their first transactions as for a business with millions of users depositing and withdrawing bitcoin.</p> |
|||
<h4 id="keys-to-the-game">Keys to the Game</h4><p>If you want to transact with bitcoin, you'll need keys. Each bitcoin address is associated with a particular key, and wallets are made up of many different keys. Keys consist of both a private key and a public key. The private key is required for spending and is extremely sensitive information, while a public key can be used to receive bitcoins and monitor a particular address. If you want to learn more about how this works, read up on <a href="https://en.wikipedia.org/wiki/Public-key_cryptography">Public-Key Cryptography</a>.</p> |
|||
<h4 id="hd-vs-non-hd,-you-mean-like-tvs?">HD vs. Non-HD, you mean like TVs?</h4><p>You may have seen references to "HD" wallets and wondered what that means. HD in this context does not mean "high definition," as I assumed it did at first, but rather "hierarchical deterministic." An HD wallet takes a <em>hierarchy</em> of keys in order and makes it so any key in that sequence can be <em>determined</em> by the one before it. This means that if you can produce the first key in the hierarchy, you can then generate a practically unlimited number of subsequent keys. The specification for HD wallets as implemented in bcoin is defined by <a href="https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki">Bitcoin Improvement Proposal (BIP) 32</a>.</p> |
|||
<p>Non-HD wallets, on the other hand, contain keys that are unrelated to one another. Backing up such a wallet means each key must be preserved individually. Not only is this more cumbersome, but it means that backups can quickly become out of date as new keys are added to the wallet. With an HD wallet, as long as you hold on to the seed - the data needed to recreate the first key - you will be able to recover every other key.</p> |
|||
<p>While bcoin uses HD wallets, it does allow you to import individual keys into a wallet. This can be a handy feature in certain cases, but it means you'll need to backup any imported keys separately as they will not be recoverable simply by using your seed.</p> |
|||
<p>But what exactly is the seed for an HD wallet? It can come in several forms, but bcoin implements <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki">BIP39</a> which enables seeds to be represented by a mnemonic made up of a fixed set of common words. This means your seed can be easily spoken, written down, or perhaps even memorized. But be careful! Your seed can be used to recover and spend everything in your HD wallet (except for the aforementioned imported keys), so treat it like you would an actual wallet with cash in it.</p> |
|||
<p>By default, mnemonics in bcoin are made up of twelve words representing 128 bits of entropy. This is a common standard that is far and away beyond what cutting edge computers can hope to crack via <a href="https://en.wikipedia.org/wiki/Brute-force_attack">brute force</a>. But if you want additional entropy, bcoin supports up to 512 bits of entropy which makes a 48 word mnemonic.</p> |
|||
<h3 id="accounts">Accounts</h3><p>Wallets in bcoin are partitioned into accounts. When you first create a wallet, a "default" account is created automatically along with it. Accounts can be used to track and manage separate sets of keys all within a single wallet. For example, a business can use accounts to generate distinct addresses for depositors or to segregate customer funds internally. </p> |
|||
<p>Bcoin implements <a href="https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki">BIP44</a> as a method of generating unlimited accounts deterministically. This adds additional dimensions to the hierarchy described above, meaning the same seed that can recover all your keys can also recover all your addresses.</p> |
|||
<p>Each account also comes with its own "extended public key," a piece of data that can be used to generate all public keys for that account in deterministic fashion. This means, for instance, that a business can create limitless deposit addresses for its users without having to touch its critical private keys or seed. Remember that public keys can be used for receiving bitcoins, but not for spending, so a public key falling into the wrong hands will not immediately result in theft. </p> |
|||
<h3 id="watch-only-wallets">Watch Only Wallets</h3><p>Speaking of not touching private keys, bcoin gives you the option to create wallets that are "watch only." Watch only wallets don't contain <em>any</em> private keys, which means they can't be used to spend the bitcoins they receive. However, they work perfectly fine for creating addresses, receiving bitcoins, and detecting incoming transactions. Using watch only wallets where appropriate reduces the risk of your keys and bitcoin being stolen and is good security practice.</p> |
|||
<p>Accounts always inherit the watch only behavior of their parent wallet. In other words, a watch only wallet will have exclusively watch only accounts while a regular wallet will have only regular accounts. Accordingly, you can't import private keys into a watch only wallet or public keys into regular wallets. If you try to mix and match watch only wallets and keys with bcoin, you're gonna have a bad time.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ curl http://127.0.0.1:18332/wallet/watchonlywallet/import -X POST -d <span class="token string">'{"account":"default" |
|||
,"privateKey":"cNZfR3NhQ9oCP3pTjvPZETUuTW |
|||
Zo2k6EXtfczvbWyv7FdjMhppvJ"}'</span> |
|||
<span class="token punctuation">{</span> |
|||
<span class="token string">"error"</span><span class="token keyword">:</span> <span class="token punctuation">{</span> |
|||
<span class="token string">"type"</span><span class="token keyword">:</span> <span class="token string">"Error"</span>, |
|||
<span class="token string">"message"</span><span class="token keyword">:</span> <span class="token string">"Cannot import privkey into watch-only wallet."</span> |
|||
<span class="token punctuation">}</span> |
|||
<span class="token punctuation">}</span> |
|||
~$ curl http://127.0.0.1:18332/wallet/privatekeywallet/import -X POST -d <span class="token string">'{"account":"default","publicKey":"02f4f200cb9391f8bbcc0a35e1f654b9b993b214a04ae7efd0313f4d4bf3d95745"}'</span><span class="token punctuation">{</span> |
|||
<span class="token string">"error"</span><span class="token keyword">:</span> <span class="token punctuation">{</span> |
|||
<span class="token string">"type"</span><span class="token keyword">:</span> <span class="token string">"Error"</span>, |
|||
<span class="token string">"message"</span><span class="token keyword">:</span> <span class="token string">"Cannot import pubkey into non watch-only wallet."</span> |
|||
<span class="token punctuation">}</span> |
|||
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h3 id="api-authentication">API Authentication</h3><p>Bcoin can run as a server and allow you to interact with your wallets via a <a href="http://bcoin.io/api-docs/index.html?shell--curl#wallet">REST API</a>. It also allows you protect wallets from unauthenticated requests by running the server with the <code>wallet-auth</code> option. Each wallet you create has a <code>token</code> value that must be passed in with each request. Tokens, like accounts and keys, can also be deterministically generated using your HD seed. This means you can change the token on a wallet as often as you'd like.</p> |
|||
<h3 id="recovery">Recovery</h3><p>By using the HD standards mentioned above, bcoin allows one to easily restore or transfer their entire wallet to different wallet implementations. By providing just the mnemonic, one can fully recover their wallet to a fresh instance of bcoin or any other software that properly implements BIP33, BIP39, and BIP44, like the <a href="https://trezor.io/">Trezor</a> hardware wallet.</p> |
|||
<h2 id="examples">Examples</h2><p>Enough chit chat, let's get down to business on how to create wallets, accounts, and keys with bcoin.</p> |
|||
<h3 id="nodejs">Node.js</h3><p>Below is a demo using javascript to instantiate a wallet and output important data and keys. Since bcoin is modular, you can easily use just the wallet functionality as I've done here.</p> |
|||
<h4 id="setup">Setup</h4><p>With the <a href="https://www.npmjs.com/package/bcoin">bcoin package</a> installed, we'll first import bcoin and open a wallet database in memory.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token comment" spellcheck="true">//import the bcoin module and set it to testnet</span> |
|||
<span class="token keyword">const</span> bcoin <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'bcoin'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">set</span><span class="token punctuation">(</span><span class="token string">'testnet'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> WalletDB <span class="token operator">=</span> bcoin<span class="token punctuation">.</span>walletdb<span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> WalletKey <span class="token operator">=</span> bcoin<span class="token punctuation">.</span>walletkey<span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> KeyRing <span class="token operator">=</span> bcoin<span class="token punctuation">.</span>keyring<span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> Mnemonic <span class="token operator">=</span> bcoin<span class="token punctuation">.</span>hd<span class="token punctuation">.</span>Mnemonic<span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> HD <span class="token operator">=</span> bcoin<span class="token punctuation">.</span>hd<span class="token punctuation">;</span> |
|||
|
|||
<span class="token function">walletExample</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">catch</span><span class="token punctuation">(</span>console<span class="token punctuation">.</span>error<span class="token punctuation">.</span><span class="token function">bind</span><span class="token punctuation">(</span>console<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
|
|||
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">walletExample</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> |
|||
<span class="token comment" spellcheck="true">//for demonstration purposes, we'll be creating a temporary wallet in memory</span> |
|||
<span class="token keyword">const</span> wdb <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WalletDB</span><span class="token punctuation">(</span><span class="token punctuation">{</span> db<span class="token punctuation">:</span> <span class="token string">'memory'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">await</span> wdb<span class="token punctuation">.</span><span class="token function">open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="creating-a-wallet">Creating a Wallet</h4><p>Creating a wallet in our database takes only one line.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token comment" spellcheck="true">//creates and returns a Wallet object from scratch using a random master key and default options</span> |
|||
<span class="token keyword">const</span> wallet <span class="token operator">=</span> <span class="token keyword">await</span> wdb<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>wallet<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">/*{ |
|||
wid: 2, |
|||
id: 'WLTdx4aYEPmmrQiYNwPop4nLtbpTEdJYwrN4', |
|||
network: 'testnet', |
|||
initialized: true, |
|||
accountDepth: 1, |
|||
token: 'eeae267e99d112793b892a8e30f89b1e1e0ba0d4984c2e6f09fc7931e750af5a', //the token you'll need to use the REST API with `wallet-auth` set to true |
|||
tokenDepth: 0, |
|||
state: |
|||
{ wid: undefined, |
|||
id: undefined, |
|||
tx: 0, |
|||
coin: 0, |
|||
unconfirmed: 0, |
|||
confirmed: 0 }, |
|||
master: |
|||
{ encrypted: false, |
|||
key: { xprivkey: 'tprv8ZgxMBicQKsPdcD55gci7HBednWRaosU4CkAHNEAs3kAAj9m8TVrEzxAW3EPrTrFevVssHCCoRsA37vB65SUZs727k45Nz1Cjmy4tyaSFeR' }, //the keys to the castle, guard this carefully! |
|||
mnemonic: |
|||
{ bits: 128, |
|||
language: 'english', |
|||
entropy: '04a50a56fbaaadc26a2b1690ec74243f', |
|||
phrase: 'again choose noble warrior print thrive post glare movie glove animal legal', //the keys to the castle in human readable form |
|||
passphrase: '' } }, |
|||
account: |
|||
{ wid: 2, |
|||
name: 'default', |
|||
network: <Network: testnet>, |
|||
initialized: true, |
|||
witness: false, |
|||
watchOnly: false, |
|||
type: 'pubkeyhash', |
|||
m: 1, |
|||
n: 1, |
|||
accountIndex: 0, |
|||
receiveDepth: 1, |
|||
changeDepth: 1, |
|||
nestedDepth: 0, |
|||
lookahead: 10, |
|||
address: <Address: type=pubkeyhash version=-1 str=mhNHETXFKDk7ZpGg3iEZb7guWZ2fbCuFjv>, |
|||
nestedAddress: null, |
|||
accountKey: 'tpubDDZ1r85SUsur87eW6uCrWancnCVHSLf5YcXzudCF6qBUQguR8upC6pgSuzxahDkf75SQ4LJ3R4x5NvfgQPmNjxhg2pcHzBCKcG2fBUQJ5U5', //the extended public key that can be used to generate receiving addresses for this account |
|||
keys: [] } |
|||
}*/</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="creating-accounts-and-receiving-addresses">Creating Accounts and Receiving Addresses</h4><p>You can start generating addresses with our first account right away.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token keyword">const</span> account <span class="token operator">=</span> <span class="token keyword">await</span> wallet<span class="token punctuation">.</span><span class="token function">getAccount</span><span class="token punctuation">(</span><span class="token string">'default'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//now we have a wallet and default account, let's get our first and current receiving address</span> |
|||
<span class="token keyword">const</span> key0 <span class="token operator">=</span> account<span class="token punctuation">.</span><span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token string">'string'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//this will be the same value as seen in the 'address' property under 'account' in our wallet above</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key0<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//mhNHETXFKDk7ZpGg3iEZb7guWZ2fbCuFjv</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//we can skip ahead if we want, grabbing the hundredth key in the heirarchy like so</span> |
|||
<span class="token keyword">const</span> key100 <span class="token operator">=</span> account<span class="token punctuation">.</span><span class="token function">deriveReceive</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//ok, technically this is the hundred-and-first key because the sequence is zero-based</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>key100<span class="token punctuation">.</span><span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token string">'string'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//mjVdQqQYWBpE6YzKyMRd96LxCMoJyeTX2i</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><p>You can also create a second account with a custom name.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token comment" spellcheck="true">// let's create another account for hypothetical customer John Doe</span> |
|||
<span class="token keyword">const</span> jdAccount <span class="token operator">=</span> <span class="token keyword">await</span> wallet<span class="token punctuation">.</span><span class="token function">createAccount</span><span class="token punctuation">(</span><span class="token punctuation">{</span>name<span class="token punctuation">:</span> <span class="token string">'john_doe'</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdAccount<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">/*{ |
|||
wid: 2, |
|||
name: '1', |
|||
network: <Network: testnet>, |
|||
initialized: true, |
|||
witness: false, |
|||
watchOnly: false, |
|||
type: 'pubkeyhash', |
|||
m: 1, |
|||
n: 1, |
|||
accountIndex: 1, |
|||
receiveDepth: 1, |
|||
changeDepth: 1, |
|||
nestedDepth: 0, |
|||
lookahead: 10, |
|||
address: <Address: type=pubkeyhash version=-1 str=muCSbWC6z1tAr2i1M5BKPWEZ8zapzcKfKh>, |
|||
nestedAddress: null, |
|||
accountKey: 'tpubDDZ1r85SUsur9txJF5ziLRD6757E1Q7x6VLfPby4YKqAdNwgmrkXBNDzMowxYJVoAizd7CCLHELY5X2HYzh6YurbH9vMyQJN |
|||
T92n87z22yX', |
|||
keys: [] |
|||
}*/</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//Mr. Doe wants to make 10 deposits, let's get him a unique address for each one</span> |
|||
<span class="token keyword">const</span> depositAddressesToPrint <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">for</span><span class="token punctuation">(</span><span class="token keyword">var</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span> i<span class="token operator"><</span>depositAddressesToPrint<span class="token punctuation">;</span> i<span class="token operator">++</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdAccount<span class="token punctuation">.</span><span class="token function">deriveReceive</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token string">'string'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token punctuation">}</span> |
|||
<span class="token comment" spellcheck="true">/* |
|||
muCSbWC6z1tAr2i1M5BKPWEZ8zapzcKfKh |
|||
n4TWmQyPQ8mAr2oEfbBzKF8Dw6LXXBidYJ |
|||
ms1jRu71BvEsJ4K3dMFrKFUnB8axZQdmSq |
|||
mn8xFgB68RjWGdKPVb8Up4P4v5MyqPoEQj |
|||
mzfXXKRXJBjTGRFrrg4wm1XPsdU9TLoN6T |
|||
n36TShvFCDaWgCMHHszUGiczA7Tcru4AQp |
|||
mnZBaquULuUhtwwxKTuxWNF7ZDMDNxScJd |
|||
mfpwjevu3FY4ZsWPd31J9oBH1qrxZLF1tH |
|||
mhTrDspHReXThUmMeo8dVJHqhkyHG8VPZ1 |
|||
mxKo27kJpNazq9Q3cQ7458k2S2vcQar9Pd |
|||
*/</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="getting-private-keys">Getting Private Keys</h4><p>Bcoin handles your private keys automatically for things like sending transactions and signing messages, but you can also manually extract private keys from a wallet.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token comment" spellcheck="true">//the keys above are only good for receiving bitcoins, not spending them</span> |
|||
<span class="token comment" spellcheck="true">//let's get the extended private key for John Doe's account, which can be used to generate every private key for the account</span> |
|||
<span class="token keyword">const</span> jdExtendedPrivateKey <span class="token operator">=</span> wallet<span class="token punctuation">.</span>master<span class="token punctuation">.</span>key<span class="token punctuation">.</span><span class="token function">deriveAccount</span><span class="token punctuation">(</span><span class="token number">44</span><span class="token punctuation">,</span> jdAccount<span class="token punctuation">.</span>accountIndex<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//44 is the fixed purpose for bip44 accounts </span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdExtendedPrivateKey<span class="token punctuation">.</span><span class="token function">xprivkey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//tprv8gryhi3CLWEBGRvWMSL7w1YyY3bHr4w3XBjt75vm842mntgv9Tvvzsc8Bf3NZt13ydD5QZaJVShMudE33egMhSLnEM41t5UUhRj5wA5u8Sc</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//for good measure, let's get the private key for John's first receiving address</span> |
|||
<span class="token keyword">const</span> branch <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//the branch for receiving addresses</span> |
|||
<span class="token keyword">const</span> index <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> <span class="token comment" spellcheck="true">//index of 0 means the first key among the receiving addresses</span> |
|||
<span class="token keyword">const</span> jdPrivateKey0 <span class="token operator">=</span> jdExtendedPrivateKey<span class="token punctuation">.</span><span class="token function">derive</span><span class="token punctuation">(</span>branch<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">derive</span><span class="token punctuation">(</span>index<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> jdWalletKey0 <span class="token operator">=</span> WalletKey<span class="token punctuation">.</span><span class="token function">fromHD</span><span class="token punctuation">(</span>jdAccount<span class="token punctuation">,</span> jdPrivateKey0<span class="token punctuation">,</span> branch<span class="token punctuation">,</span> index<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//the private key below can be imported into almost any bitcoin wallet, HD or non-HD, and used to spend coins from the corresponding address</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdWalletKey0<span class="token punctuation">.</span><span class="token function">getPrivateKey</span><span class="token punctuation">(</span><span class="token string">'base58'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//cNZfR3NhQ9oCP3pTjvPZETUuTWZo2k6EXtfczvbWyv7FdjMhppvJ</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="generating-mnemonics-and-recovering-keys">Generating Mnemonics and Recovering Keys</h4><p>Finally, you can create mnemonics manually and seed new wallets with them. And if you need to generate keys from a mnemonic you provide - either by recreating a wallet or by extracting specific keys - you can do that as well.</p> |
|||
<pre class="snippet line-numbers language-javascript"><code class="line-numbers language-javascript"><span class="token comment" spellcheck="true">//can wegenerate a mnemonic with twice as many bits of entropy to future proof against brute force attacks from the next millenium? sure we can.</span> |
|||
<span class="token keyword">const</span> mnemonic24 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Mnemonic</span><span class="token punctuation">(</span><span class="token punctuation">{</span>bits<span class="token punctuation">:</span> <span class="token number">256</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>mnemonic24<span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//page unknown ladder thunder airport merry run ball inject clinic danger valley equip consider normal twist casual duck essay almost trade regular two segment</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//what if we need to recover the wallet we've created above? no problem.</span> |
|||
<span class="token keyword">const</span> mnemonic <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Mnemonic</span><span class="token punctuation">(</span><span class="token string">'again choose noble warrior print thrive post glare movie glove animal legal'</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> masterKey <span class="token operator">=</span> HD<span class="token punctuation">.</span><span class="token function">fromMnemonic</span><span class="token punctuation">(</span>mnemonic<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//this wallet will generate all the same accounts, keys, addresses, and tokens if swapped in for the 'wallet' variable in examples above</span> |
|||
<span class="token keyword">const</span> recoveredWallet <span class="token operator">=</span> <span class="token keyword">await</span> wdb<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span>master<span class="token punctuation">:</span> masterKey<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
|
|||
<span class="token comment" spellcheck="true">//we can also recover only the keys for John Doe's first receiving address without recreating the wallet or account</span> |
|||
<span class="token comment" spellcheck="true">//this time we'll skip instantiating the account and use the BIP44 path for the second account, first branch, and first index on bitcoin testnet</span> |
|||
<span class="token keyword">const</span> jdRecoveredPrivateKey <span class="token operator">=</span> masterKey<span class="token punctuation">.</span><span class="token function">derivePath</span><span class="token punctuation">(</span><span class="token string">"m/44'/1'/1'/0/0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token keyword">const</span> jdKeyRing <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">KeyRing</span><span class="token punctuation">(</span>jdRecoveredPrivateKey<span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//our output should be the same as what we logged to the console earlier in this example</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdKeyRing<span class="token punctuation">.</span><span class="token function">getAddress</span><span class="token punctuation">(</span><span class="token string">'string'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//muCSbWC6z1tAr2i1M5BKPWEZ8zapzcKfKh</span> |
|||
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>jdKeyRing<span class="token punctuation">.</span><span class="token function">getPrivateKey</span><span class="token punctuation">(</span><span class="token string">'base58'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> |
|||
<span class="token comment" spellcheck="true">//cNZfR3NhQ9oCP3pTjvPZETUuTWZo2k6EXtfczvbWyv7FdjMhppvJ</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h3 id="command-line-examples-against-a-local-bcoin-server">Command Line Examples against a Local bcoin Server</h3><p>If you already have bcoin <a href="https://github.com/bcoin-org/bcoin/wiki/Beginner's-Guide">set up as a full node</a>, you can use the command line to create wallets and demonstrate some of the topics I discussed in this guide. My examples below are against a running testnet bcoin instance with <code>wallet-auth</code> set to true.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet create guide1 |
|||
<span class="token punctuation">{</span> |
|||
<span class="token string">"network"</span><span class="token keyword">:</span> <span class="token string">"testnet"</span>, |
|||
<span class="token string">"wid"</span><span class="token keyword">:</span> 2, |
|||
<span class="token string">"id"</span><span class="token keyword">:</span> <span class="token string">"guide1"</span>, |
|||
<span class="token string">"initialized"</span><span class="token keyword">:</span> true, |
|||
<span class="token string">"watchOnly"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"accountDepth"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"token"</span><span class="token keyword">:</span> <span class="token string">"c88bc2fda2f265bc00c8fd28771c62695dbbddfd05ef2510f9e0afbec14818ba"</span>, |
|||
<span class="token string">"tokenDepth"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"state"</span><span class="token keyword">:</span> <span class="token punctuation">{</span> |
|||
<span class="token string">"tx"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"coin"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"unconfirmed"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"confirmed"</span><span class="token keyword">:</span> 0 |
|||
<span class="token punctuation">}</span>, |
|||
<span class="token string">"master"</span><span class="token keyword">:</span> <span class="token punctuation">{</span> |
|||
<span class="token string">"encrypted"</span><span class="token keyword">:</span> <span class="token boolean">false</span> |
|||
<span class="token punctuation">}</span>, |
|||
<span class="token string">"account"</span><span class="token keyword">:</span> <span class="token punctuation">{</span> |
|||
<span class="token string">"name"</span><span class="token keyword">:</span> <span class="token string">"default"</span>, |
|||
<span class="token string">"initialized"</span><span class="token keyword">:</span> true, |
|||
<span class="token string">"witness"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"watchOnly"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"type"</span><span class="token keyword">:</span> <span class="token string">"pubkeyhash"</span>, |
|||
<span class="token string">"m"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"n"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"accountIndex"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"receiveDepth"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"changeDepth"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"nestedDepth"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"lookahead"</span><span class="token keyword">:</span> 10, |
|||
<span class="token string">"receiveAddress"</span><span class="token keyword">:</span> <span class="token string">"mirZQBLNFsjgxRC6STfCJU71nXqSon9U17"</span>, |
|||
<span class="token string">"nestedAddress"</span><span class="token keyword">:</span> null, |
|||
<span class="token string">"changeAddress"</span><span class="token keyword">:</span> <span class="token string">"n3qdAvsVk7v4q4CAp25SSPsfcBARJexSUr"</span>, |
|||
<span class="token string">"accountKey"</span><span class="token keyword">:</span> <span class="token string">"tpubDCsPHK6xw9CziuN6o7tk1rubLopp5ipy4rDsapkA12KYdcuLXNH7frWUcWsMiFjU5Jxqp2d37SidfmvAahsLqon14wXtor7uQvjLZscb2fh"</span>, |
|||
<span class="token string">"keys"</span><span class="token keyword">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> |
|||
<span class="token punctuation">}</span> |
|||
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="auth-tokens">Auth Tokens</h4><p>See that <code>token</code>? We'll be needing that. With the token, we can do things like query our wallet balance.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet balance --id guide1 --token c88bc2fda2f265bc00c8fd28771c62695d |
|||
bbddfd05ef2510f9e0afbec14818ba |
|||
<span class="token punctuation">{</span> |
|||
<span class="token string">"wid"</span><span class="token keyword">:</span> 2, |
|||
<span class="token string">"id"</span><span class="token keyword">:</span> <span class="token string">"guide1"</span>, |
|||
<span class="token string">"account"</span><span class="token keyword">:</span> -1, |
|||
<span class="token string">"unconfirmed"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"confirmed"</span><span class="token keyword">:</span> 0 |
|||
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><p>Without it, we get a 403 Forbidden error.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet balance --id guide1Error: Status code: 403. |
|||
at HTTPClient._request <span class="token punctuation">(</span>/opt/bitnami/nodejs/lib/node_modules/bcoin/lib/http/client.js:229:11<span class="token punctuation">)</span> |
|||
at process._tickCallback <span class="token punctuation">(</span>internal/process/next_tick.js:109:7<span class="token punctuation">)</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><p>However, we can change our token for this wallet as often as we'd like. In a production-like setting, you'd probably want to encrypt the wallet with a passphrase which would also be required for the <code>retoken</code> call below. </p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet retoken --id guide1 --token c88bc2fda2f265bc00c8fd28771c62695dbbddfd05ef2510f9e0afbec14818ba |
|||
26ea429fe1c0da8505c9b0e61a46343d802779d73393ee72130df0fb1a9eaa7e</code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h4 id="creating-an-account">Creating an Account</h4><p>With our new token, let's create an account for John Doe's sister, Jane.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet --id guide1 account create jane_doe --token 26ea429fe1c0da8505c9b0e61a46343d802779d73393ee72130df0fb1a9eaa7e |
|||
<span class="token punctuation">{</span> |
|||
<span class="token string">"wid"</span><span class="token keyword">:</span> 2, |
|||
<span class="token string">"id"</span><span class="token keyword">:</span> <span class="token string">"guide1"</span>, |
|||
<span class="token string">"name"</span><span class="token keyword">:</span> <span class="token string">"jane_doe"</span>, |
|||
<span class="token string">"initialized"</span><span class="token keyword">:</span> true, |
|||
<span class="token string">"witness"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"watchOnly"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"type"</span><span class="token keyword">:</span> <span class="token string">"pubkeyhash"</span>, |
|||
<span class="token string">"m"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"n"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"accountIndex"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"receiveDepth"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"changeDepth"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"nestedDepth"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"lookahead"</span><span class="token keyword">:</span> 10, |
|||
<span class="token string">"receiveAddress"</span><span class="token keyword">:</span> <span class="token string">"n4RwFEkSV7MSxBqqvNziakuGgeS8XFusKq"</span>, |
|||
<span class="token string">"nestedAddress"</span><span class="token keyword">:</span> null, |
|||
<span class="token string">"changeAddress"</span><span class="token keyword">:</span> <span class="token string">"mfaHH8ESM8pzoR1wLSSRQS89kpaBi9dBVt"</span>, |
|||
<span class="token string">"accountKey"</span><span class="token keyword">:</span> <span class="token string">"tpubDCsPHK6xw9CzjZQMnqwoZjLjMHqbkWjNYakAatZ9ktAf6Lou2H7jw2h93x24zT86BadMMmCAsp69yuUjBsGgHkfC41TpgXMPzSZRFxu3Ghi"</span>, |
|||
<span class="token string">"keys"</span><span class="token keyword">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> |
|||
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><p>We already have the first receiving address for Jane in <code>receiveAddress</code> above, but let's get one more for good measure.</p> |
|||
<pre class="snippet line-numbers language-bash"><code class="line-numbers language-bash">~$ bcoin wallet --id guide1 address --account jane_doe --token 26ea429fe1c0da8505c9b0e61a46343d802779d73393ee72130df0fb1a9eaa7e |
|||
<span class="token punctuation">{</span> |
|||
<span class="token string">"network"</span><span class="token keyword">:</span> <span class="token string">"testnet"</span>, |
|||
<span class="token string">"wid"</span><span class="token keyword">:</span> 2, |
|||
<span class="token string">"id"</span><span class="token keyword">:</span> <span class="token string">"guide1"</span>, |
|||
<span class="token string">"name"</span><span class="token keyword">:</span> <span class="token string">"jane_doe"</span>, |
|||
<span class="token string">"account"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"branch"</span><span class="token keyword">:</span> 0, |
|||
<span class="token string">"index"</span><span class="token keyword">:</span> 1, |
|||
<span class="token string">"witness"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"nested"</span><span class="token keyword">:</span> false, |
|||
<span class="token string">"publicKey"</span><span class="token keyword">:</span> <span class="token string">"02dda1237f65e26d05451fb96b15e85c3fb5c420ebdfcf31835857c38daa8ef5d6"</span>, |
|||
<span class="token string">"script"</span><span class="token keyword">:</span> null, |
|||
<span class="token string">"program"</span><span class="token keyword">:</span> null, |
|||
<span class="token string">"type"</span><span class="token keyword">:</span> <span class="token string">"pubkeyhash"</span>, |
|||
<span class="token string">"address"</span><span class="token keyword">:</span> <span class="token string">"mqDhGEywrWDm5DHw71Qxm5U8Lc6WvhZVeM"</span> |
|||
<span class="token punctuation">}</span></code><button class="copy-button"><img src="../assets/images/clippy.svg" alt="Copy to clipboard"></button></pre><h2 id="conclusion">Conclusion</h2><p>After reading this guide, you should have a decent understanding of not only the concepts behind bitcoin wallets, but also of how to go about creating and managing them with bcoin. Now you can integrate bcoin's wallet functionality directly into your application, or run bcoin as a full node and interact with it for your wallet creation needs. Good luck!</p> |
|||
|
|||
|
|||
<!-- END OF GUIDE --> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</article> |
|||
<!-- END OF ARTICLE CONTAINER --> |
|||
|
|||
</div> |
|||
<!-- END BLOG CONTENT --> |
|||
|
|||
|
|||
|
|||
</div><!-- .row --> |
|||
|
|||
</div> |
|||
</section> |
|||
<!-- END NEW BLOGS --> |
|||
|
|||
</div><!-- .row --> |
|||
|
|||
</div> |
|||
</section> |
|||
<!-- END BLOGS --> |
|||
|
|||
|
|||
<!-- PARALLAX DOCS CTA --> |
|||
<section class="module bg-white-alfa-30 parallax color-white" data-background="../assets/images/bg-header.jpg"> |
|||
<div class="container"> |
|||
|
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<div class="text-center"> |
|||
<h2 class="montserrat text-uppercase m-b-30">Ready to start building? Read the docs!</h2> |
|||
<a href="http://bcoin.io/docs/index.html" target="_blank" class="btn btn-lg btn-purple">Documentation</a> |
|||
</div> |
|||
</div> |
|||
</div><!-- .row --> |
|||
|
|||
</div> |
|||
</section> |
|||
<!-- END PARALLAX DOCS CTA --> |
|||
|
|||
<!-- FOOTER --> |
|||
<footer id="footer" class="footer-minimal"> |
|||
<div class="container"> |
|||
|
|||
<div class="row"> |
|||
<div class="col-sm-12"> |
|||
<ul class="social-icons social-icons-circle text-center m-b-35"> |
|||
<li><a href="https://twitter.com/bcoin"><i class="fa fa-twitter"></i></a></li> |
|||
<li><a href="https://github.com/bcoin-org/bcoin"><i class="fa fa-github"></i></a></li> |
|||
|
|||
|
|||
<li><a href="../slack-signup.html" target="_blank"><i class="fa fa-slack"></i></a></li> |
|||
</ul> |
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12 text-center m-b-35"> |
|||
<img class="m-b-35 QR-code" src="../assets/images/donation_QR.png"/> |
|||
<p class="m-0"><strong>Bcoin Development Donation Address:</strong><br />3Bi9H1hzCHWJoFEjc4xzVzEMywi35dyvsV</p> |
|||
|
|||
</div> |
|||
</div> |
|||
<div class="row"> |
|||
<div class="col-sm-12 text-center"> |
|||
<p class="m-0">Copyright <a href="#">bcoin.io, Purse</a>, 2017, All Rights Reserved.</p> |
|||
|
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</footer> |
|||
<!-- END FOOTER --> |
|||
|
|||
</div> |
|||
<!-- /WRAPPER --> |
|||
|
|||
<!-- JAVASCRIPT FILES --> |
|||
|
|||
<script src="../assets/js/jquery-2.2.3.min.js"></script> |
|||
<script src="http://maps.googleapis.com/maps/api/js?v=3"></script> |
|||
<script src="../assets/bootstrap/js/bootstrap.min.js"></script> |
|||
<script src="../assets/js/plugins.min.js"></script> |
|||
<script src="../assets/js/stickyfill.min.js"></script> |
|||
<script src="../assets/js/custom.min.js"></script> |
|||
<script src="../assets/js/clipboard.min.js"></script> |
|||
<script async defer src="../assets/js/prism.js"></script> |
|||
<script> |
|||
var copyCode = new Clipboard('.copy-button', { |
|||
target: function(trigger) { |
|||
return trigger.previousElementSibling; |
|||
} |
|||
}); |
|||
|
|||
copyCode.on('success', function(event) { |
|||
event.trigger.classList.add('success'); |
|||
event.clearSelection(); |
|||
// event.trigger.textContent = 'Copied!'; |
|||
window.setTimeout(function() { |
|||
event.trigger.classList.remove('success'); |
|||
}, 2000); |
|||
}); |
|||
</script> |
|||
|
|||
<!-- github button js --> |
|||
<script async defer src="https://buttons.github.io/buttons.js"></script> |
|||
|
|||
</body> |
|||
</html> |
Loading…
Reference in new issue