Skip to content

Commit d2f53ba

Browse files
Merge pull request #5730 from BitGo/BTC-0-move-ln-update
2 parents cffd664 + f374f41 commit d2f53ba

File tree

2 files changed

+102
-90
lines changed

2 files changed

+102
-90
lines changed

modules/abstract-lightning/src/wallet/lightning.ts

Lines changed: 1 addition & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
decodeOrElse,
1111
} from '@bitgo/sdk-core';
1212
import * as t from 'io-ts';
13-
import { createMessageSignature, deriveLightningServiceSharedSecret, unwrapLightningCoinSpecific } from '../lightning';
13+
import { createMessageSignature, unwrapLightningCoinSpecific } from '../lightning';
1414
import {
1515
CreateInvoiceBody,
1616
Invoice,
@@ -20,8 +20,6 @@ import {
2020
LightningKeychain,
2121
LndCreatePaymentResponse,
2222
SubmitPaymentParams,
23-
UpdateLightningWalletClientRequest,
24-
UpdateLightningWalletEncryptedRequest,
2523
Transaction,
2624
TransactionQuery,
2725
PaymentInfo,
@@ -90,91 +88,6 @@ export async function getLightningAuthKeychains(wallet: sdkcore.IWallet): Promis
9088
return { userAuthKey, nodeAuthKey };
9189
}
9290

93-
function encryptWalletUpdateRequest(
94-
wallet: sdkcore.IWallet,
95-
params: UpdateLightningWalletClientRequest,
96-
userAuthKey: LightningAuthKeychain
97-
): UpdateLightningWalletEncryptedRequest {
98-
const coinName = wallet.coin() as 'tlnbtc' | 'lnbtc';
99-
100-
const requestWithEncryption: Partial<UpdateLightningWalletClientRequest & UpdateLightningWalletEncryptedRequest> = {
101-
...params,
102-
};
103-
104-
const userAuthXprv = wallet.bitgo.decrypt({
105-
password: params.passphrase,
106-
input: userAuthKey.encryptedPrv,
107-
});
108-
109-
if (params.signerTlsKey) {
110-
requestWithEncryption.encryptedSignerTlsKey = wallet.bitgo.encrypt({
111-
password: params.passphrase,
112-
input: params.signerTlsKey,
113-
});
114-
}
115-
116-
if (params.signerAdminMacaroon) {
117-
requestWithEncryption.encryptedSignerAdminMacaroon = wallet.bitgo.encrypt({
118-
password: params.passphrase,
119-
input: params.signerAdminMacaroon,
120-
});
121-
}
122-
123-
if (params.signerMacaroon) {
124-
requestWithEncryption.encryptedSignerMacaroon = wallet.bitgo.encrypt({
125-
password: deriveLightningServiceSharedSecret(coinName, userAuthXprv).toString('hex'),
126-
input: params.signerMacaroon,
127-
});
128-
}
129-
130-
return t.exact(UpdateLightningWalletEncryptedRequest).encode(requestWithEncryption);
131-
}
132-
133-
/**
134-
* Updates the coin-specific configuration for a Lightning Wallet.
135-
*
136-
* @param {Wallet} wallet - Wallet.
137-
* @param {UpdateLightningWalletClientRequest} params - The parameters containing the updated wallet-specific details.
138-
* - `encryptedSignerMacaroon` (optional): This macaroon is used by the watch-only node to ask the signer node to sign transactions.
139-
* Encrypted with ECDH secret key from private key of wallet's user auth key and public key of lightning service.
140-
* - `encryptedSignerAdminMacaroon` (optional): Generated when initializing the wallet of the signer node.
141-
* Encrypted with client's wallet passphrase.
142-
* - `signerHost` (optional): The host address of the Lightning signer node.
143-
* - `encryptedSignerTlsKey` (optional): The wallet passphrase encrypted TLS key of the signer.
144-
* - `passphrase` (required): The wallet passphrase.
145-
* - `signerTlsCert` (optional): The TLS certificate of the signer.
146-
* - `watchOnlyAccounts` (optional): These are the accounts used to initialize the watch-only wallet.
147-
* @returns {Promise<unknown>} A promise resolving to the updated wallet response or throwing an error if the update fails.
148-
*/
149-
export async function updateWalletCoinSpecific(
150-
wallet: sdkcore.IWallet,
151-
params: UpdateLightningWalletClientRequest
152-
): Promise<unknown> {
153-
sdkcore.decodeOrElse(
154-
UpdateLightningWalletClientRequest.name,
155-
UpdateLightningWalletClientRequest,
156-
params,
157-
(errors) => {
158-
// DON'T throw errors from decodeOrElse. It could leak sensitive information.
159-
throw new Error(`Invalid params for lightning specific update wallet`);
160-
}
161-
);
162-
163-
const { userAuthKey } = await getLightningAuthKeychains(wallet);
164-
const updateRequestWithEncryption = encryptWalletUpdateRequest(wallet, params, userAuthKey);
165-
const signature = createMessageSignature(
166-
updateRequestWithEncryption,
167-
wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKey.encryptedPrv })
168-
);
169-
const coinSpecific = {
170-
[wallet.coin()]: {
171-
signedRequest: updateRequestWithEncryption,
172-
signature,
173-
},
174-
};
175-
return await wallet.bitgo.put(wallet.url()).send({ coinSpecific }).result();
176-
}
177-
17891
export interface ILightningWallet {
17992
/**
18093
* Creates a lightning invoice

modules/abstract-lightning/src/wallet/selfCustodialLightning.ts

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,105 @@
11
import * as sdkcore from '@bitgo/sdk-core';
2-
import { BackupResponse } from '../codecs';
3-
import { ILightningWallet, LightningWallet } from './lightning';
2+
import {
3+
BackupResponse,
4+
LightningAuthKeychain,
5+
UpdateLightningWalletClientRequest,
6+
UpdateLightningWalletEncryptedRequest,
7+
} from '../codecs';
8+
import { getLightningAuthKeychains, ILightningWallet, LightningWallet } from './lightning';
9+
import { createMessageSignature, deriveLightningServiceSharedSecret, isLightningCoinName } from '../lightning';
10+
import * as t from 'io-ts';
11+
12+
function encryptWalletUpdateRequest(
13+
wallet: sdkcore.IWallet,
14+
params: UpdateLightningWalletClientRequest,
15+
userAuthKey: LightningAuthKeychain
16+
): UpdateLightningWalletEncryptedRequest {
17+
const coinName = wallet.coin() as 'tlnbtc' | 'lnbtc';
18+
19+
const requestWithEncryption: Partial<UpdateLightningWalletClientRequest & UpdateLightningWalletEncryptedRequest> = {
20+
...params,
21+
};
22+
23+
const userAuthXprv = wallet.bitgo.decrypt({
24+
password: params.passphrase,
25+
input: userAuthKey.encryptedPrv,
26+
});
27+
28+
if (params.signerTlsKey) {
29+
requestWithEncryption.encryptedSignerTlsKey = wallet.bitgo.encrypt({
30+
password: params.passphrase,
31+
input: params.signerTlsKey,
32+
});
33+
}
34+
35+
if (params.signerAdminMacaroon) {
36+
requestWithEncryption.encryptedSignerAdminMacaroon = wallet.bitgo.encrypt({
37+
password: params.passphrase,
38+
input: params.signerAdminMacaroon,
39+
});
40+
}
41+
42+
if (params.signerMacaroon) {
43+
requestWithEncryption.encryptedSignerMacaroon = wallet.bitgo.encrypt({
44+
password: deriveLightningServiceSharedSecret(coinName, userAuthXprv).toString('hex'),
45+
input: params.signerMacaroon,
46+
});
47+
}
48+
49+
return t.exact(UpdateLightningWalletEncryptedRequest).encode(requestWithEncryption);
50+
}
51+
52+
/**
53+
* Updates the coin-specific configuration for a Lightning Wallet.
54+
*
55+
* @param {Wallet} wallet - Wallet.
56+
* @param {UpdateLightningWalletClientRequest} params - The parameters containing the updated wallet-specific details.
57+
* - `encryptedSignerMacaroon` (optional): This macaroon is used by the watch-only node to ask the signer node to sign transactions.
58+
* Encrypted with ECDH secret key from private key of wallet's user auth key and public key of lightning service.
59+
* - `encryptedSignerAdminMacaroon` (optional): Generated when initializing the wallet of the signer node.
60+
* Encrypted with client's wallet passphrase.
61+
* - `signerHost` (optional): The host address of the Lightning signer node.
62+
* - `encryptedSignerTlsKey` (optional): The wallet passphrase encrypted TLS key of the signer.
63+
* - `passphrase` (required): The wallet passphrase.
64+
* - `signerTlsCert` (optional): The TLS certificate of the signer.
65+
* - `watchOnlyAccounts` (optional): These are the accounts used to initialize the watch-only wallet.
66+
* @returns {Promise<unknown>} A promise resolving to the updated wallet response or throwing an error if the update fails.
67+
*/
68+
export async function updateWalletCoinSpecific(
69+
wallet: sdkcore.IWallet,
70+
params: UpdateLightningWalletClientRequest
71+
): Promise<unknown> {
72+
if (!isLightningCoinName(wallet.coin())) {
73+
throw new Error(`cant update lightning wallet coin specific for coin ${wallet.type()}`);
74+
}
75+
if (wallet.type() !== 'hot') {
76+
throw new Error(`cant update lightning wallet coin specific for wallet type ${wallet.type()}`);
77+
}
78+
79+
sdkcore.decodeOrElse(
80+
UpdateLightningWalletClientRequest.name,
81+
UpdateLightningWalletClientRequest,
82+
params,
83+
(errors) => {
84+
// DON'T throw errors from decodeOrElse. It could leak sensitive information.
85+
throw new Error(`Invalid params for lightning specific update wallet`);
86+
}
87+
);
88+
89+
const { userAuthKey } = await getLightningAuthKeychains(wallet);
90+
const updateRequestWithEncryption = encryptWalletUpdateRequest(wallet, params, userAuthKey);
91+
const signature = createMessageSignature(
92+
updateRequestWithEncryption,
93+
wallet.bitgo.decrypt({ password: params.passphrase, input: userAuthKey.encryptedPrv })
94+
);
95+
const coinSpecific = {
96+
[wallet.coin()]: {
97+
signedRequest: updateRequestWithEncryption,
98+
signature,
99+
},
100+
};
101+
return await wallet.bitgo.put(wallet.url()).send({ coinSpecific }).result();
102+
}
4103

5104
export interface ISelfCustodialLightningWallet extends ILightningWallet {
6105
/**

0 commit comments

Comments
 (0)