本文介绍了如何使用 Node.js 和 gRPC 编写一个简单的 lnd 客户端。内容包括环境配置、依赖安装、客户端创建以及示例代码, 演示了简单RPC调用、响应流式RPC和双向流式RPC的使用方法,以及如何使用Macaroons进行身份验证。文章还提供了在线API文档链接。
node.js
在 Javascript 中编写一个简单的 lnd
客户端首先,你需要初始化一个简单的 nodejs 项目:
npm init (或者 npm init -f,如果你想使用默认值而不做任何提示)
然后你需要安装 Javascript grpc 和 proto loader 库的依赖:
npm install @grpc/grpc-js @grpc/proto-loader --save
你还需要将 lnd
的 lightning.proto
文件复制到你的项目目录中
(或者至少是你的 Javascript 代码可以访问到的地方)。
lightning.proto
文件位于 lnd
源码的 lnrpc
目录中。
每次你使用 Javascript gRPC 时,你都需要导入 @grpc/grpc-js
,加载
lightning.proto
,并创建一个到你的客户端的连接,就像这样。
请注意,当使用 IP 地址连接到节点时(例如,192.168.1.21 而不是 localhost),你需要将 --tlsextraip=192.168.1.21
添加到你的 lnd
配置中,并重新生成证书(删除 tls.cert 和 tls.key 并重启 lnd)。
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const fs = require("fs");
// 由于更新的 ECDSA 生成的 tls.cert,我们需要让 gRPC 知道
// 我们需要使用该密码套件,否则当我们与 lnd rpc 服务器通信时,
// 会出现握手错误。
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'
// 我们需要给 proto loader 一些额外的选项,否则代码将无法
// 完全与 lnd 一起工作。
const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
};
const packageDefinition = protoLoader.loadSync('lightning.proto', loaderOptions);
// Lnd 证书位于 Linux 上的 ~/.lnd/tls.cert 和
// Mac 上的 ~/Library/Application Support/Lnd/tls.cert
let lndCert = fs.readFileSync("~/.lnd/tls.cert");
let credentials = grpc.credentials.createSsl(lndCert);
let lnrpcDescriptor = grpc.loadPackageDefinition(packageDefinition);
let lnrpc = lnrpcDescriptor.lnrpc;
let lightning = new lnrpc.Lightning('localhost:10009', credentials);
让我们来看一些 Javascript gRPC 客户端的例子。这些例子
假设你至少运行了两个 lnd
节点,其中一个节点的 RPC 位置在默认的 localhost:10009
,并且两个节点之间有一个开放的通道。
lightning.getInfo({}, function(err, response) {
if (err) {
console.log('Error: ' + err);
}
console.log('GetInfo:', response);
});
你应该在你的控制台中得到类似这样的东西:
GetInfo: { identity_pubkey: '03c892e3f3f077ea1e381c081abb36491a2502bc43ed37ffb82e264224f325ff27',
alias: '',
num_pending_channels: 0,
num_active_channels: 1,
num_inactive_channels: 0,
num_peers: 1,
block_height: 1006,
block_hash: '198ba1dc43b4190e507fa5c7aea07a74ec0009a9ab308e1736dbdab5c767ff8e',
synced_to_chain: false,
testnet: false,
chains: [ 'bitcoin' ] }
let call = lightning.subscribeInvoices({});
call.on('data', function(invoice) {
console.log(invoice);
})
.on('end', function() {
// 服务器已完成发送
})
.on('status', function(status) {
// 处理状态
console.log("Current status" + status);
});
现在,在 localhost:10009
为你的节点创建一个 invoice 并且从另一个节点向
它发送一笔支付。
$ lncli addinvoice --amt=100
{
"r_hash": <RHASH>,
"pay_req": <PAYMENT_REQUEST>
}
$ lncli sendpayment --pay_req=<PAYMENT_REQUEST>
你的 Javascript 控制台现在应该显示最近满足的 invoice 的详细信息。
这个例子有一些依赖:
$ npm install --save async lodash
你可以在 shell 中运行以下命令,或者将其放在程序中并像这样运行它
node script.js
// 加载一些特定于此示例的库
const async = require('async');
const _ = require('lodash');
let dest_pubkey = <RECEIVER_ID_PUBKEY>;
let dest_pubkey_bytes = new Buffer(dest_pubkey, "hex");
// 在双向流上设置一个监听器
let call = lightning.sendPayment();
call.on('data', function(payment) {
console.log("Payment sent:");
console.log(payment);
});
call.on('end', function() {
// 服务器已完成
console.log("END");
});
// 你可以像这样发送单笔支付
call.write({ dest: dest_pubkey_bytes, amt: 6969 });
// 或者像这样发送一堆
function paymentSender(destination, amount) {
return function(callback) {
console.log("Sending " + amount + " satoshis");
console.log("To: " + destination);
call.write({
dest: destination,
amt: amount
});
_.delay(callback, 2000);
};
}
let payment_senders = [];
for (let i = 0; i < 10; i++) {
payment_senders[i] = paymentSender(dest_pubkey_bytes, 100);
}
async.series(payment_senders, function() {
call.end();
});
这个例子会每 2 秒发送一笔100 satoshis 的支付。
要使用 macaroons 进行身份验证,你需要将 macaroon 包含在每个请求的元数据中。
以下代码段会将 macaroon 自动添加到每个请求:
const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
};
const packageDefinition = protoLoader.loadSync('lightning.proto', loaderOptions);
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA'
// Lnd admin macaroon 位于 Linux 上的 ~/.lnd/data/chain/bitcoin/simnet/admin.macaroon 和
// Mac 上的 ~/Library/Application Support/Lnd/data/chain/bitcoin/simnet/admin.macaroon
let m = fs.readFileSync('~/.lnd/data/chain/bitcoin/simnet/admin.macaroon');
let macaroon = m.toString('hex');
// 构建元数据凭证
let metadata = new grpc.Metadata()
metadata.add('macaroon', macaroon)
let macaroonCreds = grpc.credentials.createFromMetadataGenerator((_args, callback) => {
callback(null, metadata);
});
// 使用与之前相同的证书构建 ssl 凭证
let lndCert = fs.readFileSync("~/.lnd/tls.cert");
let sslCreds = grpc.credentials.createSsl(lndCert);
// 组合证书凭证和 macaroon 身份验证凭证
// 以便每个调用都经过正确加密和身份验证
let credentials = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
// 在创建通道时传递凭证
let lnrpcDescriptor = grpc.loadPackageDefinition(packageDefinition);
let lnrpc = lnrpcDescriptor.lnrpc;
let client = new lnrpc.Lightning('some.address:10009', credentials);
client.getInfo({}, (err, response) => {
if (err) {
console.log('Error: ' + err);
}
console.log('GetInfo:', response);
});
有了以上内容,你应该已经将所有 lnd
相关的 gRPC
依赖项本地安装在你的项目中。为了加快 Javascript 中 protofbuf
的使用,请参阅 这个官方 protobuf
参考资料,针对 Javascript。
此外,这个官方 gRPC 资源 提供了更多
关于如何从 node.js
驱动 gRPC
的细节。
有一个在线 API 文档 可用,其中显示了所有当前存在的 RPC 方法,包括有关如何使用它们的代码片段。
- 原文链接: github.com/lightningnetw...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!