mirror of
https://github.com/alexgo-io/ord-bitcoincore-rpc.git
synced 2026-01-12 22:23:21 +08:00
feat: compatible with bitcoin core 28
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
11
CHANGELOG.md
Normal file
11
CHANGELOG.md
Normal file
@@ -0,0 +1,11 @@
|
||||
CHANGELOG
|
||||
=========
|
||||
|
||||
# v0.2.0
|
||||
|
||||
- updated dependencies:
|
||||
- bitcoin: 0.15 -> 0.16
|
||||
- secp256ka: 0.11 -> 0.12
|
||||
- Client methods take `&self` instead of `&mut self`
|
||||
- added `create_raw_transaction`
|
||||
- updated `get_new_address` to Core 0.16 spec
|
||||
265
Cargo.lock
generated
Normal file
265
Cargo.lock
generated
Normal file
@@ -0,0 +1,265 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "bech32"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445"
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin"
|
||||
version = "0.30.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1945a5048598e4189e239d3f809b19bdad4845c4b2ba400d304d2dcf26d2c462"
|
||||
dependencies = [
|
||||
"bech32",
|
||||
"bitcoin-private",
|
||||
"bitcoin_hashes",
|
||||
"hex_lit",
|
||||
"secp256k1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin-private"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57"
|
||||
|
||||
[[package]]
|
||||
name = "bitcoin_hashes"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d7066118b13d4b20b23645932dfb3a81ce7e29f95726c2036fa33cd7b092501"
|
||||
dependencies = [
|
||||
"bitcoin-private",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex_lit"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "jsonrpc"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8128f36b47411cd3f044be8c1f5cc0c9e24d1d1bfdc45f0a57897b32513053f2"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "ord-bitcoincore-rpc"
|
||||
version = "0.17.2"
|
||||
dependencies = [
|
||||
"bitcoin-private",
|
||||
"jsonrpc",
|
||||
"log",
|
||||
"ord-bitcoincore-rpc-json",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ord-bitcoincore-rpc-json"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bb35088f918c775bc27fa79e372d034892b216fb7900aeedd6e06654879ad33"
|
||||
dependencies = [
|
||||
"bitcoin",
|
||||
"bitcoin-private",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.78"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1"
|
||||
version = "0.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f"
|
||||
dependencies = [
|
||||
"bitcoin_hashes",
|
||||
"rand",
|
||||
"secp256k1-sys",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1-sys"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.196"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.113"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
37
Cargo.toml
Normal file
37
Cargo.toml
Normal file
@@ -0,0 +1,37 @@
|
||||
[package]
|
||||
edition = "2024"
|
||||
name = "ord-bitcoincore-rpc"
|
||||
version = "0.17.2"
|
||||
authors = [
|
||||
"Steven Roose <steven@stevenroose.org>",
|
||||
"Jean Pierre Dudey <jeandudey@hotmail.com>",
|
||||
"Dawid Ciężarkiewicz <dpc@dpc.pw>",
|
||||
]
|
||||
description = "RPC client library for the Bitcoin Core JSON-RPC API."
|
||||
homepage = "https://github.com/alexgo-io/ord-bitcoincore-rpc"
|
||||
readme = "README.md"
|
||||
keywords = ["crypto", "bitcoin", "bitcoin-core", "rpc"]
|
||||
license = "CC0-1.0"
|
||||
repository = "https://github.com/alexgo-io/ord-bitcoincore-rpc"
|
||||
|
||||
[lib]
|
||||
name = "bitcoincore_rpc"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies.bitcoin-private]
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies.jsonrpc]
|
||||
version = "0.14.0"
|
||||
|
||||
[dependencies.log]
|
||||
version = "0.4.5"
|
||||
|
||||
[dependencies.ord-bitcoincore-rpc-json]
|
||||
version = "0.17.1"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1"
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1"
|
||||
122
LICENSE
Normal file
122
LICENSE
Normal file
@@ -0,0 +1,122 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
|
||||
18
README.md
Normal file
18
README.md
Normal file
@@ -0,0 +1,18 @@
|
||||
bitcoincore-rpc
|
||||
===============
|
||||
|
||||
Fork of https://github.com/rust-bitcoin/rust-bitcoincore-rpc for ord-brc20.
|
||||
|
||||
Rust client library for the Bitcoin Core daemon's JSON-RPC API.
|
||||
|
||||
Separate `bitcoincore-rpc-json` crate with the JSON-enabled data types used
|
||||
in the interface of this crate.
|
||||
|
||||
|
||||
## MSRV
|
||||
|
||||
please see the parent README for the current MSRV.
|
||||
|
||||
# License
|
||||
|
||||
All code is licensed using the CC0 license, as per the LICENSE file.
|
||||
47
examples/retry_client.rs
Normal file
47
examples/retry_client.rs
Normal file
@@ -0,0 +1,47 @@
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this software to
|
||||
// the public domain worldwide. This software is distributed without
|
||||
// any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication
|
||||
// along with this software.
|
||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
|
||||
extern crate bitcoincore_rpc;
|
||||
extern crate jsonrpc;
|
||||
extern crate serde;
|
||||
extern crate serde_json;
|
||||
|
||||
use bitcoincore_rpc::{Client, Error, Result, RpcApi};
|
||||
|
||||
pub struct RetryClient {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
const INTERVAL: u64 = 1000;
|
||||
const RETRY_ATTEMPTS: u8 = 10;
|
||||
|
||||
impl RpcApi for RetryClient {
|
||||
fn call<T: for<'a> serde::de::Deserialize<'a>>(
|
||||
&self,
|
||||
cmd: &str,
|
||||
args: &[serde_json::Value],
|
||||
) -> Result<T> {
|
||||
for _ in 0..RETRY_ATTEMPTS {
|
||||
match self.client.call(cmd, args) {
|
||||
Ok(ret) => return Ok(ret),
|
||||
Err(Error::JsonRpc(jsonrpc::error::Error::Rpc(ref rpcerr)))
|
||||
if rpcerr.code == -28 =>
|
||||
{
|
||||
::std::thread::sleep(::std::time::Duration::from_millis(INTERVAL));
|
||||
continue;
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
self.client.call(cmd, args)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
48
examples/test_against_node.rs
Normal file
48
examples/test_against_node.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this software to
|
||||
// the public domain worldwide. This software is distributed without
|
||||
// any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication
|
||||
// along with this software.
|
||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
|
||||
//! A very simple example used as a self-test of this library against a Bitcoin
|
||||
//! Core node.
|
||||
extern crate bitcoincore_rpc;
|
||||
|
||||
use bitcoincore_rpc::{bitcoin, Auth, Client, Error, RpcApi};
|
||||
|
||||
fn main_result() -> Result<(), Error> {
|
||||
let mut args = std::env::args();
|
||||
|
||||
let _exe_name = args.next().unwrap();
|
||||
|
||||
let url = args.next().expect("Usage: <rpc_url> <username> <password>");
|
||||
let user = args.next().expect("no user given");
|
||||
let pass = args.next().expect("no pass given");
|
||||
|
||||
let rpc = Client::new(&url, Auth::UserPass(user, pass)).unwrap();
|
||||
|
||||
let _blockchain_info = rpc.get_blockchain_info()?;
|
||||
|
||||
let best_block_hash = rpc.get_best_block_hash()?;
|
||||
println!("best block hash: {}", best_block_hash);
|
||||
let bestblockcount = rpc.get_block_count()?;
|
||||
println!("best block height: {}", bestblockcount);
|
||||
let best_block_hash_by_height = rpc.get_block_hash(bestblockcount)?;
|
||||
println!("best block hash by height: {}", best_block_hash_by_height);
|
||||
assert_eq!(best_block_hash_by_height, best_block_hash);
|
||||
|
||||
let bitcoin_block: bitcoin::Block = rpc.get_by_id(&best_block_hash)?;
|
||||
println!("best block hash by `get`: {}", bitcoin_block.header.prev_blockhash);
|
||||
let bitcoin_tx: bitcoin::Transaction = rpc.get_by_id(&bitcoin_block.txdata[0].txid())?;
|
||||
println!("tx by `get`: {}", bitcoin_tx.txid());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
main_result().unwrap();
|
||||
}
|
||||
1580
src/client.rs
Normal file
1580
src/client.rs
Normal file
File diff suppressed because it is too large
Load Diff
111
src/error.rs
Normal file
111
src/error.rs
Normal file
@@ -0,0 +1,111 @@
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this software to
|
||||
// the public domain worldwide. This software is distributed without
|
||||
// any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication
|
||||
// along with this software.
|
||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
|
||||
use std::{error, fmt, io};
|
||||
|
||||
use crate::bitcoin;
|
||||
use crate::bitcoin::hashes::hex;
|
||||
use crate::bitcoin::secp256k1;
|
||||
use jsonrpc;
|
||||
use serde_json;
|
||||
|
||||
/// The error type for errors produced in this library.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
JsonRpc(jsonrpc::error::Error),
|
||||
Hex(hex::Error),
|
||||
Json(serde_json::error::Error),
|
||||
BitcoinSerialization(bitcoin::consensus::encode::Error),
|
||||
Secp256k1(secp256k1::Error),
|
||||
Io(io::Error),
|
||||
InvalidAmount(bitcoin::amount::ParseAmountError),
|
||||
InvalidCookieFile,
|
||||
/// The JSON result had an unexpected structure.
|
||||
UnexpectedStructure,
|
||||
/// The daemon returned an error string.
|
||||
ReturnedError(String),
|
||||
}
|
||||
|
||||
impl From<jsonrpc::error::Error> for Error {
|
||||
fn from(e: jsonrpc::error::Error) -> Error {
|
||||
Error::JsonRpc(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<hex::Error> for Error {
|
||||
fn from(e: hex::Error) -> Error {
|
||||
Error::Hex(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::error::Error> for Error {
|
||||
fn from(e: serde_json::error::Error) -> Error {
|
||||
Error::Json(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::consensus::encode::Error> for Error {
|
||||
fn from(e: bitcoin::consensus::encode::Error) -> Error {
|
||||
Error::BitcoinSerialization(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<secp256k1::Error> for Error {
|
||||
fn from(e: secp256k1::Error) -> Error {
|
||||
Error::Secp256k1(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<io::Error> for Error {
|
||||
fn from(e: io::Error) -> Error {
|
||||
Error::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bitcoin::amount::ParseAmountError> for Error {
|
||||
fn from(e: bitcoin::amount::ParseAmountError) -> Error {
|
||||
Error::InvalidAmount(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::JsonRpc(ref e) => write!(f, "JSON-RPC error: {}", e),
|
||||
Error::Hex(ref e) => write!(f, "hex decode error: {}", e),
|
||||
Error::Json(ref e) => write!(f, "JSON error: {}", e),
|
||||
Error::BitcoinSerialization(ref e) => write!(f, "Bitcoin serialization error: {}", e),
|
||||
Error::Secp256k1(ref e) => write!(f, "secp256k1 error: {}", e),
|
||||
Error::Io(ref e) => write!(f, "I/O error: {}", e),
|
||||
Error::InvalidAmount(ref e) => write!(f, "invalid amount: {}", e),
|
||||
Error::InvalidCookieFile => write!(f, "invalid cookie file"),
|
||||
Error::UnexpectedStructure => write!(f, "the JSON result had an unexpected structure"),
|
||||
Error::ReturnedError(ref s) => write!(f, "the daemon returned an error string: {}", s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
"bitcoincore-rpc error"
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&dyn error::Error> {
|
||||
match *self {
|
||||
Error::JsonRpc(ref e) => Some(e),
|
||||
Error::Hex(ref e) => Some(e),
|
||||
Error::Json(ref e) => Some(e),
|
||||
Error::BitcoinSerialization(ref e) => Some(e),
|
||||
Error::Secp256k1(ref e) => Some(e),
|
||||
Error::Io(ref e) => Some(e),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
53
src/lib.rs
Normal file
53
src/lib.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this software to
|
||||
// the public domain worldwide. This software is distributed without
|
||||
// any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication
|
||||
// along with this software.
|
||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
|
||||
//! # Rust Client for Bitcoin Core API
|
||||
//!
|
||||
//! This is a client library for the Bitcoin Core JSON-RPC API.
|
||||
//!
|
||||
|
||||
#![crate_name = "bitcoincore_rpc"]
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[allow(unused)]
|
||||
#[macro_use] // `macro_use` is needed for v1.24.0 compilation.
|
||||
extern crate serde;
|
||||
|
||||
pub extern crate jsonrpc;
|
||||
|
||||
pub extern crate bitcoincore_rpc_json;
|
||||
pub use crate::json::bitcoin;
|
||||
pub use bitcoincore_rpc_json as json;
|
||||
use json::bitcoin::consensus::{Decodable, ReadExt};
|
||||
use json::bitcoin::hashes::hex::HexIterator;
|
||||
|
||||
mod client;
|
||||
mod error;
|
||||
mod queryable;
|
||||
|
||||
pub use crate::client::*;
|
||||
pub use crate::error::Error;
|
||||
pub use crate::queryable::*;
|
||||
|
||||
fn deserialize_hex<T: Decodable>(hex: &str) -> Result<T> {
|
||||
let mut reader = HexIterator::new(&hex)?;
|
||||
let object = Decodable::consensus_decode(&mut reader)?;
|
||||
if reader.read_u8().is_ok() {
|
||||
Err(Error::BitcoinSerialization(
|
||||
bitcoin::consensus::encode::Error::ParseFailed(
|
||||
"data not consumed entirely when explicitly deserializing",
|
||||
),
|
||||
))
|
||||
} else {
|
||||
Ok(object)
|
||||
}
|
||||
}
|
||||
53
src/queryable.rs
Normal file
53
src/queryable.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
// To the extent possible under law, the author(s) have dedicated all
|
||||
// copyright and related and neighboring rights to this software to
|
||||
// the public domain worldwide. This software is distributed without
|
||||
// any warranty.
|
||||
//
|
||||
// You should have received a copy of the CC0 Public Domain Dedication
|
||||
// along with this software.
|
||||
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
|
||||
//
|
||||
|
||||
use crate::bitcoin;
|
||||
use serde_json;
|
||||
|
||||
use crate::client::Result;
|
||||
use crate::client::RpcApi;
|
||||
|
||||
/// A type that can be queried from Bitcoin Core.
|
||||
pub trait Queryable<C: RpcApi>: Sized {
|
||||
/// Type of the ID used to query the item.
|
||||
type Id;
|
||||
/// Query the item using `rpc` and convert to `Self`.
|
||||
fn query(rpc: &C, id: &Self::Id) -> Result<Self>;
|
||||
}
|
||||
|
||||
impl<C: RpcApi> Queryable<C> for bitcoin::block::Block {
|
||||
type Id = bitcoin::BlockHash;
|
||||
|
||||
fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
|
||||
let rpc_name = "getblock";
|
||||
let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?, 0.into()])?;
|
||||
let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
|
||||
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: RpcApi> Queryable<C> for bitcoin::transaction::Transaction {
|
||||
type Id = bitcoin::Txid;
|
||||
|
||||
fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
|
||||
let rpc_name = "getrawtransaction";
|
||||
let hex: String = rpc.call(rpc_name, &[serde_json::to_value(id)?])?;
|
||||
let bytes: Vec<u8> = bitcoin::hashes::hex::FromHex::from_hex(&hex)?;
|
||||
Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: RpcApi> Queryable<C> for Option<crate::json::GetTxOutResult> {
|
||||
type Id = bitcoin::OutPoint;
|
||||
|
||||
fn query(rpc: &C, id: &Self::Id) -> Result<Self> {
|
||||
rpc.get_tx_out(&id.txid, id.vout, Some(true))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user