Skip to content

Commit

Permalink
feat(express): lightning wallet creation step two
Browse files Browse the repository at this point in the history
initialize signer lnd and update platform.

Ticket: BTC-1356
  • Loading branch information
saravanan7mani committed Aug 19, 2024
1 parent 7f80f20 commit dea64fa
Show file tree
Hide file tree
Showing 22 changed files with 880 additions and 43 deletions.
5 changes: 4 additions & 1 deletion modules/express/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
},
"dependencies": {
"@bitgo/sdk-core": "^27.9.0",
"@bitgo/utxo-lib": "^10.1.0",
"argparse": "^1.0.10",
"bitgo": "^38.18.1",
"bluebird": "^3.5.3",
Expand All @@ -48,7 +49,9 @@
"express": "^4.17.3",
"lodash": "^4.17.20",
"morgan": "^1.9.1",
"superagent": "^9.0.1"
"superagent": "^9.0.1",
"io-ts": "2.1.3",
"io-ts-types": "0.5.16"
},
"devDependencies": {
"@bitgo/public-types": "2.33.4",
Expand Down
4 changes: 4 additions & 0 deletions modules/express/src/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,8 @@ parser.addArgument(['--signerMode'], {
parser.addArgument(['--signerFileSystemPath'], {
help: 'Local path specifying where an Express signer machine keeps encrypted user private keys.',
});

parser.addArgument(['--lightningSignerFileSystemPath'], {
help: 'Local path specifying where an Express machine keeps lightning signer urls.',
});
export const args = () => parser.parseArgs();
11 changes: 11 additions & 0 deletions modules/express/src/clientRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ import { Config } from './config';
import { ApiResponseError } from './errors';
import { promises as fs } from 'fs';
import { retryPromise } from './retryPromise';
import {
handleCreateSignerMacaroon,
handleGetLightningWalletState,
handleInitLightningWallet,
} from './lightning/lightningRoutes';

const { version } = require('bitgo/package.json');
const pjson = require('../package.json');
Expand Down Expand Up @@ -1651,3 +1656,9 @@ export function setupSigningRoutes(app: express.Application, config: Config): vo
promiseWrapper(handleV2OFCSignPayloadInExtSigningMode)
);
}

export function setupLightningRoutes(app: express.Application, config: Config): void {
app.post('/api/v2/:coin/initwallet', parseBody, prepareBitGo(config), promiseWrapper(handleInitLightningWallet));
app.post('/api/v2/:coin/signermacaroon', parseBody, prepareBitGo(config), promiseWrapper(handleCreateSignerMacaroon));
app.get('/api/v2/:coin/wallet/:id/state', prepareBitGo(config), promiseWrapper(handleGetLightningWalletState));
}
22 changes: 18 additions & 4 deletions modules/express/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { isNil, isNumber } from 'lodash';
import 'dotenv/config';

import { args } from './args';
import { getLightningSignerConfigs } from './lightning/lightningUtils';
import { LightningSignerConfigs } from './lightning/codecs';

function readEnvVar(name, ...deprecatedAliases): string | undefined {
if (process.env[name] !== undefined && process.env[name] !== '') {
Expand Down Expand Up @@ -38,6 +40,8 @@ export interface Config {
externalSignerUrl?: string;
signerMode?: boolean;
signerFileSystemPath?: string;
lightningSignerFileSystemPath?: string;
lightningSignerConfigs?: LightningSignerConfigs;
}

export const ArgConfig = (args): Partial<Config> => ({
Expand All @@ -59,6 +63,7 @@ export const ArgConfig = (args): Partial<Config> => ({
externalSignerUrl: args.externalSignerUrl,
signerMode: args.signerMode,
signerFileSystemPath: args.signerFileSystemPath,
lightningSignerFileSystemPath: args.lightningSignerFileSystemPath,
});

export const EnvConfig = (): Partial<Config> => ({
Expand All @@ -80,6 +85,7 @@ export const EnvConfig = (): Partial<Config> => ({
externalSignerUrl: readEnvVar('BITGO_EXTERNAL_SIGNER_URL'),
signerMode: readEnvVar('BITGO_SIGNER_MODE') ? true : undefined,
signerFileSystemPath: readEnvVar('BITGO_SIGNER_FILE_SYSTEM_PATH'),
lightningSignerFileSystemPath: readEnvVar('BITGO_LIGHTNING_SIGNER_FILE_SYSTEM_PATH'),
});

export const DefaultConfig: Config = {
Expand All @@ -102,7 +108,7 @@ export const DefaultConfig: Config = {
* @param url
* @return {string}
*/
function _forceSecureUrl(url: string): string {
export function _forceSecureUrl(url: string): string {
const regex = new RegExp(/(^\w+:|^)\/\//);
if (regex.test(url)) {
return url.replace(/(^\w+:|^)\/\//, 'https://');
Expand All @@ -115,7 +121,7 @@ function _forceSecureUrl(url: string): string {
*
* Later configs have higher precedence over earlier configs.
*/
function mergeConfigs(...configs: Partial<Config>[]): Config {
async function mergeConfigs(...configs: Partial<Config>[]): Promise<Config> {
function isNilOrNaN(val: unknown): val is null | undefined | number {
return isNil(val) || (isNumber(val) && isNaN(val));
}
Expand All @@ -142,6 +148,12 @@ function mergeConfigs(...configs: Partial<Config>[]): Config {
}
}

const lightningSignerFileSystemPath = get('lightningSignerFileSystemPath');
let lightningSignerConfigs: LightningSignerConfigs | undefined;
if (lightningSignerFileSystemPath) {
lightningSignerConfigs = await getLightningSignerConfigs(lightningSignerFileSystemPath);
}

return {
port: get('port'),
bind: get('bind'),
Expand All @@ -161,11 +173,13 @@ function mergeConfigs(...configs: Partial<Config>[]): Config {
externalSignerUrl,
signerMode: get('signerMode'),
signerFileSystemPath: get('signerFileSystemPath'),
lightningSignerFileSystemPath,
lightningSignerConfigs: lightningSignerConfigs,
};
}

export const config = () => {
export const config = async () => {
const arg = ArgConfig(args());
const env = EnvConfig();
return mergeConfigs(env, arg);
return await mergeConfigs(env, arg);
};
10 changes: 8 additions & 2 deletions modules/express/src/expressApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function createHttpServer(app: express.Application): http.Server {
*/
export function startup(config: Config, baseUri: string): () => void {
return function () {
const { env, ipc, customRootUri, customBitcoinNetwork, signerMode } = config;
const { env, ipc, customRootUri, customBitcoinNetwork, signerMode, lightningSignerFileSystemPath } = config;
/* eslint-disable no-console */
console.log('BitGo-Express running');
console.log(`Environment: ${env}`);
Expand All @@ -122,6 +122,9 @@ export function startup(config: Config, baseUri: string): () => void {
if (signerMode) {
console.log(`External signer mode: ${signerMode}`);
}
if (lightningSignerFileSystemPath) {
console.log(`Lightning signer file system path: ${lightningSignerFileSystemPath}`);
}
/* eslint-enable no-console */
};
}
Expand Down Expand Up @@ -240,6 +243,9 @@ export function setupRoutes(app: express.Application, config: Config): void {
} else {
clientRoutes.setupAPIRoutes(app, config);
}
if (config.lightningSignerFileSystemPath) {
clientRoutes.setupLightningRoutes(app, config);
}
}

export function app(cfg: Config): express.Application {
Expand Down Expand Up @@ -308,7 +314,7 @@ export async function prepareIpc(ipcSocketFilePath: string) {
}

export async function init(): Promise<void> {
const cfg = config();
const cfg = await config();
const expressApp = app(cfg);

const server = await createServer(cfg, expressApp);
Expand Down
77 changes: 77 additions & 0 deletions modules/express/src/lightning/codecs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import * as t from 'io-ts';
import { NonEmptyString } from 'io-ts-types';
import { IPCustomCodec } from '@bitgo/sdk-core';

export const WalletStateCodec = t.keyof({
NON_EXISTING: 1,
LOCKED: 1,
UNLOCKED: 1,
RPC_ACTIVE: 1,
SERVER_ACTIVE: 1,
WAITING_TO_START: 1,
});

export type WalletState = t.TypeOf<typeof WalletStateCodec>;

export const LightningSignerConfigCodec = t.type({
url: NonEmptyString,
tlsCert: NonEmptyString,
});

export type LightningSignerConfig = t.TypeOf<typeof LightningSignerConfigCodec>;

export const LightningSignerConfigsCodec = t.record(t.string, LightningSignerConfigCodec);

export type LightningSignerConfigs = t.TypeOf<typeof LightningSignerConfigsCodec>;

export const GetWalletStateResponseCodec = t.type(
{
state: WalletStateCodec,
},
'GetWalletStateResponse'
);

export type GetWalletStateResponse = t.TypeOf<typeof GetWalletStateResponseCodec>;

export const InitLightningWalletRequestCodec = t.strict(
{
walletId: NonEmptyString,
passphrase: NonEmptyString,
signerIP: IPCustomCodec,
signerTlsCert: NonEmptyString,
signerTlsKey: NonEmptyString,
expressIP: IPCustomCodec,
},
'InitLightningWalletRequest'
);

export type InitLightningWalletRequest = t.TypeOf<typeof InitLightningWalletRequestCodec>;

export const CreateSignerMacaroonRequestCodec = t.strict(
{
walletId: NonEmptyString,
passphrase: NonEmptyString,
watchOnlyIP: IPCustomCodec,
},
'CreateSignerMacaroonRequest'
);

export type CreateSignerMacaroonRequest = t.TypeOf<typeof CreateSignerMacaroonRequestCodec>;

export const InitWalletResponseCodec = t.type(
{
admin_macaroon: NonEmptyString,
},
'InitWalletResponse'
);

export type InitWalletResponse = t.TypeOf<typeof InitWalletResponseCodec>;

export const BakeMacaroonResponseCodec = t.type(
{
macaroon: NonEmptyString,
},
'BakeMacaroonResponse'
);

export type BakeMacaroonResponse = t.TypeOf<typeof BakeMacaroonResponseCodec>;
Loading

0 comments on commit dea64fa

Please sign in to comment.