PHP WebShell
Текущая директория: /opt/BitGoJS/modules/express/dist/lightning
Просмотр файла: lndSignerClient.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LndSignerClient = void 0;
const https = require("https");
const superagent = require("superagent");
const sdk_core_1 = require("@bitgo/sdk-core");
const retryPromise_1 = require("../retryPromise");
const codecs_1 = require("./codecs");
const lightningUtils_1 = require("./lightningUtils");
/**
* Client for interacting with the LND signer.
*/
class LndSignerClient {
constructor(config) {
this.url = config.url;
this.httpsAgent = new https.Agent({
ca: Buffer.from(config.tlsCert, 'base64').toString('utf-8'),
});
}
/**
* Create a new LndSignerClient.
*/
static async create(walletId, config) {
const lightningSignerConfig = await (0, lightningUtils_1.getLightningSignerConfig)(walletId, config);
return new LndSignerClient(lightningSignerConfig);
}
/**
* Get the current state of the wallet from remote signer LND.
*/
async getWalletState() {
const res = await (0, retryPromise_1.retryPromise)(() => superagent.get(`${this.url}/v1/state`).agent(this.httpsAgent).send(), (err, tryCount) => {
console.log(`failed to connect to lightning signer (attempt ${tryCount}, error: ${err.message})`);
});
if (res.status !== 200) {
throw new Error(`Failed to get wallet state with status: ${res.text}`);
}
return (0, sdk_core_1.decodeOrElse)(codecs_1.GetWalletStateResponse.name, codecs_1.GetWalletStateResponse, res.body, (errors) => {
throw new Error(`Get wallet state failed: ${errors}`);
});
}
/**
* Initialize the remote signer LND wallet with the given data.
*/
async initWallet(data) {
const res = await (0, retryPromise_1.retryPromise)(() => superagent
.post(`${this.url}/v1/initwallet`)
.agent(this.httpsAgent)
.type('json')
.send({ ...data, stateless_init: true }), (err, tryCount) => {
console.log(`failed to connect to lightning signer (attempt ${tryCount}, error: ${err.message})`);
});
if (res.status !== 200) {
throw new Error(`Failed to initialize wallet with status: ${res.status}`);
}
return (0, sdk_core_1.decodeOrElse)(codecs_1.InitWalletResponse.name, codecs_1.InitWalletResponse, res.body, (_) => {
throw new Error(`Init wallet failed.`);
});
}
/**
* Bake a macaroon with the given permissions from remote signer LND.
*/
async bakeMacaroon(data, header) {
const res = await (0, retryPromise_1.retryPromise)(() => superagent
.post(`${this.url}/v1/macaroon`)
.agent(this.httpsAgent)
.set('Grpc-Metadata-macaroon', header.adminMacaroonHex)
.type('json')
.send(data), (err, tryCount) => {
console.log(`failed to connect to lightning signer (attempt ${tryCount}, error: ${err.message})`);
});
if (res.status !== 200) {
throw new Error(`Failed to bake macaroon with status: ${res.text}`);
}
return (0, sdk_core_1.decodeOrElse)(codecs_1.BakeMacaroonResponse.name, codecs_1.BakeMacaroonResponse, res.body, (errors) => {
throw new Error(`Bake macaroon failed: ${errors}`);
});
}
/**
* Unlock the wallet with the given wallet password.
*/
async unlockWallet(data) {
const res = await (0, retryPromise_1.retryPromise)(() => superagent
.post(`${this.url}/v1/unlockwallet`)
.agent(this.httpsAgent)
.type('json')
.send({ ...data, stateless_init: true }), (err, tryCount) => {
console.log(`failed to connect to lightning signer (attempt ${tryCount}, error: ${err.message})`);
});
if (res.status !== 200) {
throw new Error(`Failed to unlock wallet: ${res.text}`);
}
}
}
exports.LndSignerClient = LndSignerClient;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG5kU2lnbmVyQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpZ2h0bmluZy9sbmRTaWduZXJDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBQStCO0FBQy9CLHlDQUF5QztBQUN6Qyw4Q0FBK0M7QUFDL0Msa0RBQStDO0FBQy9DLHFDQUFtSDtBQUNuSCxxREFBNEQ7QUFFNUQ7O0dBRUc7QUFDSCxNQUFhLGVBQWU7SUFJMUIsWUFBb0IsTUFBNkI7UUFDL0MsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ2hDLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztTQUM1RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDeEIsUUFBZ0IsRUFDaEIsTUFBa0Q7UUFFbEQsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLElBQUEseUNBQXdCLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9FLE9BQU8sSUFBSSxlQUFlLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsY0FBYztRQUNsQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUEsMkJBQVksRUFDNUIsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQzFFLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2hCLE9BQU8sQ0FB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QUNMLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBaUM7UUFDbEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFBLDJCQUFZLEVBQzVCLEdBQUcsRUFBRSxDQUNILFVBQVU7YUFDUCxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxrQkFBa0IsQ0FBQzthQUNuQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzthQUN0QixJQUFJLENBQUMsTUFBTSxDQUFDO2FBQ1osSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQzVDLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0RBQWtELFFBQVEsWUFBWSxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNwRyxDQUFDLENBQ0YsQ0FBQztRQUVGLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE0QixHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMxRCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBN0hELDBDQTZIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGh0dHBzIGZyb20gJ2h0dHBzJztcbmltcG9ydCAqIGFzIHN1cGVyYWdlbnQgZnJvbSAnc3VwZXJhZ2VudCc7XG5pbXBvcnQgeyBkZWNvZGVPckVsc2UgfSBmcm9tICdAYml0Z28vc2RrLWNvcmUnO1xuaW1wb3J0IHsgcmV0cnlQcm9taXNlIH0gZnJvbSAnLi4vcmV0cnlQcm9taXNlJztcbmltcG9ydCB7IEJha2VNYWNhcm9vblJlc3BvbnNlLCBHZXRXYWxsZXRTdGF0ZVJlc3BvbnNlLCBJbml0V2FsbGV0UmVzcG9uc2UsIExpZ2h0bmluZ1NpZ25lckNvbmZpZyB9IGZyb20gJy4vY29kZWNzJztcbmltcG9ydCB7IGdldExpZ2h0bmluZ1NpZ25lckNvbmZpZyB9IGZyb20gJy4vbGlnaHRuaW5nVXRpbHMnO1xuXG4vKipcbiAqIENsaWVudCBmb3IgaW50ZXJhY3Rpbmcgd2l0aCB0aGUgTE5EIHNpZ25lci5cbiAqL1xuZXhwb3J0IGNsYXNzIExuZFNpZ25lckNsaWVudCB7XG4gIHB1YmxpYyByZWFkb25seSB1cmw6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGh0dHBzQWdlbnQ6IGh0dHBzLkFnZW50O1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoY29uZmlnOiBMaWdodG5pbmdTaWduZXJDb25maWcpIHtcbiAgICB0aGlzLnVybCA9IGNvbmZpZy51cmw7XG4gICAgdGhpcy5odHRwc0FnZW50ID0gbmV3IGh0dHBzLkFnZW50KHtcbiAgICAgIGNhOiBCdWZmZXIuZnJvbShjb25maWcudGxzQ2VydCwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGYtOCcpLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIG5ldyBMbmRTaWduZXJDbGllbnQuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGNyZWF0ZShcbiAgICB3YWxsZXRJZDogc3RyaW5nLFxuICAgIGNvbmZpZzogeyBsaWdodG5pbmdTaWduZXJGaWxlU3lzdGVtUGF0aD86IHN0cmluZyB9XG4gICk6IFByb21pc2U8TG5kU2lnbmVyQ2xpZW50PiB7XG4gICAgY29uc3QgbGlnaHRuaW5nU2lnbmVyQ29uZmlnID0gYXdhaXQgZ2V0TGlnaHRuaW5nU2lnbmVyQ29uZmlnKHdhbGxldElkLCBjb25maWcpO1xuICAgIHJldHVybiBuZXcgTG5kU2lnbmVyQ2xpZW50KGxpZ2h0bmluZ1NpZ25lckNvbmZpZyk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSB3YWxsZXQgZnJvbSByZW1vdGUgc2lnbmVyIExORC5cbiAgICovXG4gIGFzeW5jIGdldFdhbGxldFN0YXRlKCk6IFByb21pc2U8R2V0V2FsbGV0U3RhdGVSZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHJldHJ5UHJvbWlzZShcbiAgICAgICgpID0+IHN1cGVyYWdlbnQuZ2V0KGAke3RoaXMudXJsfS92MS9zdGF0ZWApLmFnZW50KHRoaXMuaHR0cHNBZ2VudCkuc2VuZCgpLFxuICAgICAgKGVyciwgdHJ5Q291bnQpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYGZhaWxlZCB0byBjb25uZWN0IHRvIGxpZ2h0bmluZyBzaWduZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0sIGVycm9yOiAke2Vyci5tZXNzYWdlfSlgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gZ2V0IHdhbGxldCBzdGF0ZSB3aXRoIHN0YXR1czogJHtyZXMudGV4dH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVjb2RlT3JFbHNlKEdldFdhbGxldFN0YXRlUmVzcG9uc2UubmFtZSwgR2V0V2FsbGV0U3RhdGVSZXNwb25zZSwgcmVzLmJvZHksIChlcnJvcnMpID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgR2V0IHdhbGxldCBzdGF0ZSBmYWlsZWQ6ICR7ZXJyb3JzfWApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemUgdGhlIHJlbW90ZSBzaWduZXIgTE5EIHdhbGxldCB3aXRoIHRoZSBnaXZlbiBkYXRhLlxuICAgKi9cbiAgYXN5bmMgaW5pdFdhbGxldChkYXRhOiB7XG4gICAgd2FsbGV0X3Bhc3N3b3JkOiBzdHJpbmc7XG4gICAgZXh0ZW5kZWRfbWFzdGVyX2tleTogc3RyaW5nO1xuICAgIG1hY2Fyb29uX3Jvb3Rfa2V5OiBzdHJpbmc7XG4gIH0pOiBQcm9taXNlPEluaXRXYWxsZXRSZXNwb25zZT4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHJldHJ5UHJvbWlzZShcbiAgICAgICgpID0+XG4gICAgICAgIHN1cGVyYWdlbnRcbiAgICAgICAgICAucG9zdChgJHt0aGlzLnVybH0vdjEvaW5pdHdhbGxldGApXG4gICAgICAgICAgLmFnZW50KHRoaXMuaHR0cHNBZ2VudClcbiAgICAgICAgICAudHlwZSgnanNvbicpXG4gICAgICAgICAgLnNlbmQoeyAuLi5kYXRhLCBzdGF0ZWxlc3NfaW5pdDogdHJ1ZSB9KSxcbiAgICAgIChlcnIsIHRyeUNvdW50KSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBmYWlsZWQgdG8gY29ubmVjdCB0byBsaWdodG5pbmcgc2lnbmVyIChhdHRlbXB0ICR7dHJ5Q291bnR9LCBlcnJvcjogJHtlcnIubWVzc2FnZX0pYCk7XG4gICAgICB9XG4gICAgKTtcblxuICAgIGlmIChyZXMuc3RhdHVzICE9PSAyMDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIGluaXRpYWxpemUgd2FsbGV0IHdpdGggc3RhdHVzOiAke3Jlcy5zdGF0dXN9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRlY29kZU9yRWxzZShJbml0V2FsbGV0UmVzcG9uc2UubmFtZSwgSW5pdFdhbGxldFJlc3BvbnNlLCByZXMuYm9keSwgKF8pID0+IHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW5pdCB3YWxsZXQgZmFpbGVkLmApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEJha2UgYSBtYWNhcm9vbiB3aXRoIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyBmcm9tIHJlbW90ZSBzaWduZXIgTE5ELlxuICAgKi9cbiAgYXN5bmMgYmFrZU1hY2Fyb29uKFxuICAgIGRhdGE6IHtcbiAgICAgIHBlcm1pc3Npb25zOiB7XG4gICAgICAgIGVudGl0eTogc3RyaW5nO1xuICAgICAgICBhY3Rpb246IHN0cmluZztcbiAgICAgIH1bXTtcbiAgICB9LFxuICAgIGhlYWRlcjogeyBhZG1pbk1hY2Fyb29uSGV4OiBzdHJpbmcgfVxuICApOiBQcm9taXNlPEJha2VNYWNhcm9vblJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgcmV0cnlQcm9taXNlKFxuICAgICAgKCkgPT5cbiAgICAgICAgc3VwZXJhZ2VudFxuICAgICAgICAgIC5wb3N0KGAke3RoaXMudXJsfS92MS9tYWNhcm9vbmApXG4gICAgICAgICAgLmFnZW50KHRoaXMuaHR0cHNBZ2VudClcbiAgICAgICAgICAuc2V0KCdHcnBjLU1ldGFkYXRhLW1hY2Fyb29uJywgaGVhZGVyLmFkbWluTWFjYXJvb25IZXgpXG4gICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgICAgIC5zZW5kKGRhdGEpLFxuICAgICAgKGVyciwgdHJ5Q291bnQpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYGZhaWxlZCB0byBjb25uZWN0IHRvIGxpZ2h0bmluZyBzaWduZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0sIGVycm9yOiAke2Vyci5tZXNzYWdlfSlgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gYmFrZSBtYWNhcm9vbiB3aXRoIHN0YXR1czogJHtyZXMudGV4dH1gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVjb2RlT3JFbHNlKEJha2VNYWNhcm9vblJlc3BvbnNlLm5hbWUsIEJha2VNYWNhcm9vblJlc3BvbnNlLCByZXMuYm9keSwgKGVycm9ycykgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBCYWtlIG1hY2Fyb29uIGZhaWxlZDogJHtlcnJvcnN9YCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVW5sb2NrIHRoZSB3YWxsZXQgd2l0aCB0aGUgZ2l2ZW4gd2FsbGV0IHBhc3N3b3JkLlxuICAgKi9cbiAgYXN5bmMgdW5sb2NrV2FsbGV0KGRhdGE6IHsgd2FsbGV0X3Bhc3N3b3JkOiBzdHJpbmcgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHJldHJ5UHJvbWlzZShcbiAgICAgICgpID0+XG4gICAgICAgIHN1cGVyYWdlbnRcbiAgICAgICAgICAucG9zdChgJHt0aGlzLnVybH0vdjEvdW5sb2Nrd2FsbGV0YClcbiAgICAgICAgICAuYWdlbnQodGhpcy5odHRwc0FnZW50KVxuICAgICAgICAgIC50eXBlKCdqc29uJylcbiAgICAgICAgICAuc2VuZCh7IC4uLmRhdGEsIHN0YXRlbGVzc19pbml0OiB0cnVlIH0pLFxuICAgICAgKGVyciwgdHJ5Q291bnQpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYGZhaWxlZCB0byBjb25uZWN0IHRvIGxpZ2h0bmluZyBzaWduZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0sIGVycm9yOiAke2Vyci5tZXNzYWdlfSlgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gdW5sb2NrIHdhbGxldDogJHtyZXMudGV4dH1gKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!