Skip to content

gRPC API

walletrs serves plaintext gRPC on WALLETRS_HOST:WALLETRS_PORT (default 127.0.0.1:50051). Use this when you have tonic / grpc-go / grpcio in your stack and want native streaming, codegen’d types, low overhead. For curl-friendly access, see the HTTP / JSON page.

The canonical walletrpc.proto lives in the walletrs repo at proto/walletrpc.proto. It is the single source of truth for every RPC, every message, and the HTTP path mapping (via (google.api.http) annotations).

Two recommended ways to consume it:

Terminal window
git submodule add https://github.com/n1rna/walletrs vendor/walletrs
git -C vendor/walletrs checkout v0.1.0

Point your build at vendor/walletrs/proto/walletrpc.proto. Bumping walletrs is a single submodule update.

If submodules don’t fit your repo conventions, download the proto from a release tag:

Terminal window
curl -o vendor/walletrpc.proto \
https://raw.githubusercontent.com/n1rna/walletrs/v0.1.0/proto/walletrpc.proto

Track the version in your dependency manifest so renovating is explicit.

build.rs:

fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::compile_protos("vendor/walletrs/proto/walletrpc.proto")?;
Ok(())
}

Cargo.toml:

[dependencies]
tonic = "0.9"
prost = "0.11"
[build-dependencies]
tonic-build = "0.9"

Calling code:

use tonic::metadata::MetadataValue;
use tonic::transport::Channel;
use tonic::Request;
pub mod walletrpc {
tonic::include_proto!("walletrpc");
}
use walletrpc::wallet_service_client::WalletServiceClient;
use walletrpc::PingRequest;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let channel = Channel::from_static("http://127.0.0.1:50051").connect().await?;
let token: MetadataValue<_> = "Bearer <YOUR_TOKEN>".parse()?;
let mut client =
WalletServiceClient::with_interceptor(channel, move |mut req: Request<()>| {
req.metadata_mut().insert("authorization", token.clone());
Ok(req)
});
let resp = client.ping(PingRequest {}).await?;
println!("ping: {:?}", resp);
Ok(())
}
Terminal window
pip install grpcio grpcio-tools
python -m grpc_tools.protoc \
--proto_path=vendor/walletrs/proto \
--python_out=. --grpc_python_out=. \
vendor/walletrs/proto/walletrpc.proto
import grpc
import walletrpc_pb2
import walletrpc_pb2_grpc
token = "YOUR_TOKEN"
with grpc.insecure_channel("127.0.0.1:50051") as channel:
stub = walletrpc_pb2_grpc.WalletServiceStub(channel)
metadata = (("authorization", f"Bearer {token}"),)
response = stub.Ping(walletrpc_pb2.PingRequest(), metadata=metadata)
print("ping:", response)
Terminal window
npm install @grpc/grpc-js @grpc/proto-loader
import * as grpc from "@grpc/grpc-js";
import * as protoLoader from "@grpc/proto-loader";
const def = protoLoader.loadSync("vendor/walletrs/proto/walletrpc.proto", {
keepCase: false,
longs: String,
enums: String,
});
const proto = (grpc.loadPackageDefinition(def) as any).walletrpc;
const client = new proto.WalletService(
"127.0.0.1:50051",
grpc.credentials.createInsecure(),
);
const meta = new grpc.Metadata();
meta.set("authorization", `Bearer ${process.env.WALLETRS_AUTH_TOKEN}`);
client.Ping({}, meta, (err: any, resp: any) => {
if (err) throw err;
console.log("ping:", resp);
});

For TLS, swap createInsecure() for createSsl(...) and point at your reverse-proxy hostname.

Every RPC except Ping requires the authorization metadata key. The expected value is Bearer <token>. Missing or wrong tokens return Status::unauthenticated. See Authentication for the full token-mode story.

walletrs uses the standard gRPC status codes for handler errors:

CodeWhen
INVALID_ARGUMENTMalformed input (e.g. Leaf hash 'X' does not match any spending path).
NOT_FOUNDWallet / managed key doesn’t exist.
UNAUTHENTICATEDMissing or wrong bearer token.
INTERNALUnexpected error inside the wallet pipeline. The Status::message carries the reason.

The HTTP gateway maps these one-to-one — see the HTTP page for the table.

The full RPC list with HTTP-path equivalents is on the HTTP / JSON page. The proto file itself is the canonical source for request / response shapes.

The proto contract follows additive semver inside a minor series — fields and RPCs land without breaking older clients. Pin the walletrs version your stubs were generated against, and bump deliberately. The CHANGELOG calls out anything backwards-incompatible.