PHP WebShell

Текущая директория: /opt/BitGoJS/modules/express/dist/src/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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG5kU2lnbmVyQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpZ2h0bmluZy9sbmRTaWduZXJDbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0JBQStCO0FBQy9CLHlDQUF5QztBQUN6Qyw4Q0FBK0M7QUFDL0Msa0RBQStDO0FBQy9DLHFDQUFtSDtBQUNuSCxxREFBNEQ7QUFFNUQ7O0dBRUc7QUFDSCxNQUFhLGVBQWU7SUFJMUIsWUFBb0IsTUFBNkI7UUFDL0MsSUFBSSxDQUFDLEdBQUcsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQ2hDLEVBQUUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQztTQUM1RCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FDeEIsUUFBZ0IsRUFDaEIsTUFBa0Q7UUFFbEQsTUFBTSxxQkFBcUIsR0FBRyxNQUFNLElBQUEseUNBQXdCLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQy9FLE9BQU8sSUFBSSxlQUFlLENBQUMscUJBQXFCLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsY0FBYztRQUNsQixNQUFNLEdBQUcsR0FBRyxNQUFNLElBQUEsMkJBQVksRUFDNUIsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLFdBQVcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQzFFLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2hCLE9BQU8s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QUssQ0FBQyxZQUFZLENBQUMsSUFBaUM7UUFDbEQsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFBLDJCQUFZLEVBQzVCLEdBQUcsRUFBRSxDQUNILFVBQVU7YUFDUCxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxrQkFBa0IsQ0FBQzthQUNuQyxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzthQUN0QixJQUFJLENBQUMsTUFBTSxDQUFDO2FBQ1osSUFBSSxDQUFDLEVBQUUsR0FBRyxJQUFJLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQzVDLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ2hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0RBQWtELFFBQVEsWUFBWSxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQztRQUNwRyxDQUFDLENBQ0YsQ0FBQztRQUVGLElBQUksR0FBRyxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUU7WUFDdEIsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7U0FDekQ7SUFDSCxDQUFDO0NBQ0Y7QUE3SEQsMENBNkhDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnO1xuaW1wb3J0ICogYXMgc3VwZXJhZ2VudCBmcm9tICdzdXBlcmFnZW50JztcbmltcG9ydCB7IGRlY29kZU9yRWxzZSB9IGZyb20gJ0BiaXRnby9zZGstY29yZSc7XG5pbXBvcnQgeyByZXRyeVByb21pc2UgfSBmcm9tICcuLi9yZXRyeVByb21pc2UnO1xuaW1wb3J0IHsgQmFrZU1hY2Fyb29uUmVzcG9uc2UsIEdldFdhbGxldFN0YXRlUmVzcG9uc2UsIEluaXRXYWxsZXRSZXNwb25zZSwgTGlnaHRuaW5nU2lnbmVyQ29uZmlnIH0gZnJvbSAnLi9jb2RlY3MnO1xuaW1wb3J0IHsgZ2V0TGlnaHRuaW5nU2lnbmVyQ29uZmlnIH0gZnJvbSAnLi9saWdodG5pbmdVdGlscyc7XG5cbi8qKlxuICogQ2xpZW50IGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBMTkQgc2lnbmVyLlxuICovXG5leHBvcnQgY2xhc3MgTG5kU2lnbmVyQ2xpZW50IHtcbiAgcHVibGljIHJlYWRvbmx5IHVybDogc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgaHR0cHNBZ2VudDogaHR0cHMuQWdlbnQ7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihjb25maWc6IExpZ2h0bmluZ1NpZ25lckNvbmZpZykge1xuICAgIHRoaXMudXJsID0gY29uZmlnLnVybDtcbiAgICB0aGlzLmh0dHBzQWdlbnQgPSBuZXcgaHR0cHMuQWdlbnQoe1xuICAgICAgY2E6IEJ1ZmZlci5mcm9tKGNvbmZpZy50bHNDZXJ0LCAnYmFzZTY0JykudG9TdHJpbmcoJ3V0Zi04JyksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IExuZFNpZ25lckNsaWVudC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgY3JlYXRlKFxuICAgIHdhbGxldElkOiBzdHJpbmcsXG4gICAgY29uZmlnOiB7IGxpZ2h0bmluZ1NpZ25lckZpbGVTeXN0ZW1QYXRoPzogc3RyaW5nIH1cbiAgKTogUHJvbWlzZTxMbmRTaWduZXJDbGllbnQ+IHtcbiAgICBjb25zdCBsaWdodG5pbmdTaWduZXJDb25maWcgPSBhd2FpdCBnZXRMaWdodG5pbmdTaWduZXJDb25maWcod2FsbGV0SWQsIGNvbmZpZyk7XG4gICAgcmV0dXJuIG5ldyBMbmRTaWduZXJDbGllbnQobGlnaHRuaW5nU2lnbmVyQ29uZmlnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIHdhbGxldCBmcm9tIHJlbW90ZSBzaWduZXIgTE5ELlxuICAgKi9cbiAgYXN5bmMgZ2V0V2FsbGV0U3RhdGUoKTogUHJvbWlzZTxHZXRXYWxsZXRTdGF0ZVJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgcmV0cnlQcm9taXNlKFxuICAgICAgKCkgPT4gc3VwZXJhZ2VudC5nZXQoYCR7dGhpcy51cmx9L3YxL3N0YXRlYCkuYWdlbnQodGhpcy5odHRwc0FnZW50KS5zZW5kKCksXG4gICAgICAoZXJyLCB0cnlDb3VudCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgZmFpbGVkIHRvIGNvbm5lY3QgdG8gbGlnaHRuaW5nIHNpZ25lciAoYXR0ZW1wdCAke3RyeUNvdW50fSwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9KWApO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBnZXQgd2FsbGV0IHN0YXRlIHdpdGggc3RhdHVzOiAke3Jlcy50ZXh0fWApO1xuICAgIH1cblxuICAgIHJldHVybiBkZWNvZGVPckVsc2UoR2V0V2FsbGV0U3RhdGVSZXNwb25zZS5uYW1lLCBHZXRXYWxsZXRTdGF0ZVJlc3BvbnNlLCByZXMuYm9keSwgKGVycm9ycykgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBHZXQgd2FsbGV0IHN0YXRlIGZhaWxlZDogJHtlcnJvcnN9YCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgcmVtb3RlIHNpZ25lciBMTkQgd2FsbGV0IHdpdGggdGhlIGdpdmVuIGRhdGEuXG4gICAqL1xuICBhc3luYyBpbml0V2FsbGV0KGRhdGE6IHtcbiAgICB3YWxsZXRfcGFzc3dvcmQ6IHN0cmluZztcbiAgICBleHRlbmRlZF9tYXN0ZXJfa2V5OiBzdHJpbmc7XG4gICAgbWFjYXJvb25fcm9vdF9rZXk6IHN0cmluZztcbiAgfSk6IFByb21pc2U8SW5pdFdhbGxldFJlc3BvbnNlPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgcmV0cnlQcm9taXNlKFxuICAgICAgKCkgPT5cbiAgICAgICAgc3VwZXJhZ2VudFxuICAgICAgICAgIC5wb3N0KGAke3RoaXMudXJsfS92MS9pbml0d2FsbGV0YClcbiAgICAgICAgICAuYWdlbnQodGhpcy5odHRwc0FnZW50KVxuICAgICAgICAgIC50eXBlKCdqc29uJylcbiAgICAgICAgICAuc2VuZCh7IC4uLmRhdGEsIHN0YXRlbGVzc19pbml0OiB0cnVlIH0pLFxuICAgICAgKGVyciwgdHJ5Q291bnQpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2coYGZhaWxlZCB0byBjb25uZWN0IHRvIGxpZ2h0bmluZyBzaWduZXIgKGF0dGVtcHQgJHt0cnlDb3VudH0sIGVycm9yOiAke2Vyci5tZXNzYWdlfSlgKTtcbiAgICAgIH1cbiAgICApO1xuXG4gICAgaWYgKHJlcy5zdGF0dXMgIT09IDIwMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSB3YWxsZXQgd2l0aCBzdGF0dXM6ICR7cmVzLnN0YXR1c31gKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVjb2RlT3JFbHNlKEluaXRXYWxsZXRSZXNwb25zZS5uYW1lLCBJbml0V2FsbGV0UmVzcG9uc2UsIHJlcy5ib2R5LCAoXykgPT4ge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbml0IHdhbGxldCBmYWlsZWQuYCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQmFrZSBhIG1hY2Fyb29uIHdpdGggdGhlIGdpdmVuIHBlcm1pc3Npb25zIGZyb20gcmVtb3RlIHNpZ25lciBMTkQuXG4gICAqL1xuICBhc3luYyBiYWtlTWFjYXJvb24oXG4gICAgZGF0YToge1xuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgZW50aXR5OiBzdHJpbmc7XG4gICAgICAgIGFjdGlvbjogc3RyaW5nO1xuICAgICAgfVtdO1xuICAgIH0sXG4gICAgaGVhZGVyOiB7IGFkbWluTWFjYXJvb25IZXg6IHN0cmluZyB9XG4gICk6IFByb21pc2U8QmFrZU1hY2Fyb29uUmVzcG9uc2U+IHtcbiAgICBjb25zdCByZXMgPSBhd2FpdCByZXRyeVByb21pc2UoXG4gICAgICAoKSA9PlxuICAgICAgICBzdXBlcmFnZW50XG4gICAgICAgICAgLnBvc3QoYCR7dGhpcy51cmx9L3YxL21hY2Fyb29uYClcbiAgICAgICAgICAuYWdlbnQodGhpcy5odHRwc0FnZW50KVxuICAgICAgICAgIC5zZXQoJ0dycGMtTWV0YWRhdGEtbWFjYXJvb24nLCBoZWFkZXIuYWRtaW5NYWNhcm9vbkhleClcbiAgICAgICAgICAudHlwZSgnanNvbicpXG4gICAgICAgICAgLnNlbmQoZGF0YSksXG4gICAgICAoZXJyLCB0cnlDb3VudCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgZmFpbGVkIHRvIGNvbm5lY3QgdG8gbGlnaHRuaW5nIHNpZ25lciAoYXR0ZW1wdCAke3RyeUNvdW50fSwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9KWApO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBiYWtlIG1hY2Fyb29uIHdpdGggc3RhdHVzOiAke3Jlcy50ZXh0fWApO1xuICAgIH1cblxuICAgIHJldHVybiBkZWNvZGVPckVsc2UoQmFrZU1hY2Fyb29uUmVzcG9uc2UubmFtZSwgQmFrZU1hY2Fyb29uUmVzcG9uc2UsIHJlcy5ib2R5LCAoZXJyb3JzKSA9PiB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEJha2UgbWFjYXJvb24gZmFpbGVkOiAke2Vycm9yc31gKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVbmxvY2sgdGhlIHdhbGxldCB3aXRoIHRoZSBnaXZlbiB3YWxsZXQgcGFzc3dvcmQuXG4gICAqL1xuICBhc3luYyB1bmxvY2tXYWxsZXQoZGF0YTogeyB3YWxsZXRfcGFzc3dvcmQ6IHN0cmluZyB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVzID0gYXdhaXQgcmV0cnlQcm9taXNlKFxuICAgICAgKCkgPT5cbiAgICAgICAgc3VwZXJhZ2VudFxuICAgICAgICAgIC5wb3N0KGAke3RoaXMudXJsfS92MS91bmxvY2t3YWxsZXRgKVxuICAgICAgICAgIC5hZ2VudCh0aGlzLmh0dHBzQWdlbnQpXG4gICAgICAgICAgLnR5cGUoJ2pzb24nKVxuICAgICAgICAgIC5zZW5kKHsgLi4uZGF0YSwgc3RhdGVsZXNzX2luaXQ6IHRydWUgfSksXG4gICAgICAoZXJyLCB0cnlDb3VudCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhgZmFpbGVkIHRvIGNvbm5lY3QgdG8gbGlnaHRuaW5nIHNpZ25lciAoYXR0ZW1wdCAke3RyeUNvdW50fSwgZXJyb3I6ICR7ZXJyLm1lc3NhZ2V9KWApO1xuICAgICAgfVxuICAgICk7XG5cbiAgICBpZiAocmVzLnN0YXR1cyAhPT0gMjAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byB1bmxvY2sgd2FsbGV0OiAke3Jlcy50ZXh0fWApO1xuICAgIH1cbiAgfVxufVxuIl19

Выполнить команду


Для локальной разработки. Не используйте в интернете!