@aibtc/mcp-server 1.48.0 → 1.49.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/services/lightning/provider.d.ts +68 -0
- package/dist/services/lightning/provider.d.ts.map +1 -0
- package/dist/services/lightning/provider.js +8 -0
- package/dist/services/lightning/provider.js.map +1 -0
- package/dist/services/lightning/spark-provider.d.ts +41 -0
- package/dist/services/lightning/spark-provider.d.ts.map +1 -0
- package/dist/services/lightning/spark-provider.js +165 -0
- package/dist/services/lightning/spark-provider.js.map +1 -0
- package/dist/services/lightning-manager.d.ts +96 -0
- package/dist/services/lightning-manager.d.ts.map +1 -0
- package/dist/services/lightning-manager.js +226 -0
- package/dist/services/lightning-manager.js.map +1 -0
- package/dist/services/sbtc-deposit.service.d.ts.map +1 -1
- package/dist/services/sbtc-deposit.service.js +7 -13
- package/dist/services/sbtc-deposit.service.js.map +1 -1
- package/dist/services/unisat-indexer.d.ts +5 -0
- package/dist/services/unisat-indexer.d.ts.map +1 -1
- package/dist/services/unisat-indexer.js +8 -0
- package/dist/services/unisat-indexer.js.map +1 -1
- package/dist/services/x402.service.d.ts.map +1 -1
- package/dist/services/x402.service.js +228 -0
- package/dist/services/x402.service.js.map +1 -1
- package/dist/tools/bitcoin.tools.d.ts.map +1 -1
- package/dist/tools/bitcoin.tools.js +26 -46
- package/dist/tools/bitcoin.tools.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +3 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/lightning.tools.d.ts +11 -0
- package/dist/tools/lightning.tools.d.ts.map +1 -0
- package/dist/tools/lightning.tools.js +333 -0
- package/dist/tools/lightning.tools.js.map +1 -0
- package/dist/tools/styx.tools.d.ts.map +1 -1
- package/dist/tools/styx.tools.js +28 -30
- package/dist/tools/styx.tools.js.map +1 -1
- package/dist/utils/l402-protocol.d.ts +64 -0
- package/dist/utils/l402-protocol.d.ts.map +1 -0
- package/dist/utils/l402-protocol.js +114 -0
- package/dist/utils/l402-protocol.js.map +1 -0
- package/package.json +3 -1
- package/skill/SKILL.md +1 -1
- package/dist/services/ordinal-indexer.d.ts +0 -128
- package/dist/services/ordinal-indexer.d.ts.map +0 -1
- package/dist/services/ordinal-indexer.js +0 -126
- package/dist/services/ordinal-indexer.js.map +0 -1
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightning Network provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implementations wrap a specific Lightning backend (e.g. Spark SDK, NWC) and
|
|
5
|
+
* expose a uniform shape the L402 interceptor and lightning tools can depend on.
|
|
6
|
+
*/
|
|
7
|
+
export interface LightningProvider {
|
|
8
|
+
/**
|
|
9
|
+
* Pay a BOLT-11 Lightning invoice.
|
|
10
|
+
*
|
|
11
|
+
* @param bolt11 - BOLT-11 encoded Lightning invoice
|
|
12
|
+
* @param maxFeeSats - Optional maximum routing fee in sats (provider default applies when omitted)
|
|
13
|
+
* @returns Payment preimage (hex) and fees paid (in sats)
|
|
14
|
+
*/
|
|
15
|
+
payInvoice(bolt11: string, maxFeeSats?: number): Promise<{
|
|
16
|
+
preimage: string;
|
|
17
|
+
feesPaid: number;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Create a BOLT-11 Lightning invoice for receiving a payment.
|
|
21
|
+
*
|
|
22
|
+
* @param amountSats - Amount to invoice in sats
|
|
23
|
+
* @param memo - Optional description
|
|
24
|
+
* @returns BOLT-11 invoice string and payment hash (hex)
|
|
25
|
+
*/
|
|
26
|
+
createInvoice(amountSats: number, memo?: string): Promise<{
|
|
27
|
+
bolt11: string;
|
|
28
|
+
paymentHash: string;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* Get the spendable Lightning balance in sats.
|
|
32
|
+
*/
|
|
33
|
+
getBalance(): Promise<{
|
|
34
|
+
balanceSats: number;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Get an on-chain deposit address for funding the Lightning wallet from L1 BTC.
|
|
38
|
+
*/
|
|
39
|
+
getDepositAddress(): Promise<string>;
|
|
40
|
+
/**
|
|
41
|
+
* Claim an on-chain deposit (credits the Lightning balance).
|
|
42
|
+
*
|
|
43
|
+
* Implementations should follow the canonical Spark deposit flow:
|
|
44
|
+
* 1. Fetch a quote from the SSP (signed `creditAmountSats`).
|
|
45
|
+
* 2. Submit the quote's signature with the claim.
|
|
46
|
+
*
|
|
47
|
+
* The caller commits to whatever the SSP's signed quote charges in fees;
|
|
48
|
+
* callers that need a max-fee guard should fetch the quote separately and
|
|
49
|
+
* inspect it before invoking this method.
|
|
50
|
+
*
|
|
51
|
+
* @param transactionId - Bitcoin transaction id sending BTC to the deposit address
|
|
52
|
+
* @param outputIndex - Optional output index of the deposit (vout). Required when
|
|
53
|
+
* the deposit is not at the default vout the SSP would auto-detect.
|
|
54
|
+
* @returns Number of sats credited to the Lightning balance and the resulting
|
|
55
|
+
* Spark transfer id (so callers can correlate the claim with the
|
|
56
|
+
* subsequent transfer).
|
|
57
|
+
*/
|
|
58
|
+
claimDeposit(transactionId: string, outputIndex?: number): Promise<{
|
|
59
|
+
creditedSats: number;
|
|
60
|
+
transferId: string;
|
|
61
|
+
}>;
|
|
62
|
+
/**
|
|
63
|
+
* Optional: return a Lightning address (user@domain) the wallet can receive to.
|
|
64
|
+
* Implementations may return null when unsupported.
|
|
65
|
+
*/
|
|
66
|
+
getLightningAddress?(): Promise<string | null>;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/services/lightning/provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,iBAAiB;IAChC;;;;;;OAMG;IACH,UAAU,CACR,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEnD;;;;;;OAMG;IACH,aAAa,CACX,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEpD;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/C;;OAEG;IACH,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAErC;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEzD;;;OAGG;IACH,mBAAmB,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightning Network provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implementations wrap a specific Lightning backend (e.g. Spark SDK, NWC) and
|
|
5
|
+
* expose a uniform shape the L402 interceptor and lightning tools can depend on.
|
|
6
|
+
*/
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/services/lightning/provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spark SDK-backed LightningProvider implementation.
|
|
3
|
+
*
|
|
4
|
+
* Wraps SparkWallet (from @buildonspark/spark-sdk) to satisfy the
|
|
5
|
+
* LightningProvider interface. Auth is handled by the SDK using the user's
|
|
6
|
+
* BIP39 identity key — no API key is required.
|
|
7
|
+
*/
|
|
8
|
+
import type { Network } from "../../config/networks.js";
|
|
9
|
+
import type { LightningProvider } from "./provider.js";
|
|
10
|
+
export declare class SparkLightningProvider implements LightningProvider {
|
|
11
|
+
private readonly wallet;
|
|
12
|
+
private readonly network;
|
|
13
|
+
private constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Initialize a Spark-backed provider from a mnemonic.
|
|
16
|
+
* The wallet itself is managed by the lightning-manager singleton — this
|
|
17
|
+
* factory is the only place the SDK is touched directly.
|
|
18
|
+
*/
|
|
19
|
+
static initialize(mnemonic: string, network: Network): Promise<SparkLightningProvider>;
|
|
20
|
+
payInvoice(bolt11: string, maxFeeSats?: number): Promise<{
|
|
21
|
+
preimage: string;
|
|
22
|
+
feesPaid: number;
|
|
23
|
+
}>;
|
|
24
|
+
createInvoice(amountSats: number, memo?: string): Promise<{
|
|
25
|
+
bolt11: string;
|
|
26
|
+
paymentHash: string;
|
|
27
|
+
}>;
|
|
28
|
+
getBalance(): Promise<{
|
|
29
|
+
balanceSats: number;
|
|
30
|
+
}>;
|
|
31
|
+
getDepositAddress(): Promise<string>;
|
|
32
|
+
claimDeposit(transactionId: string, outputIndex?: number): Promise<{
|
|
33
|
+
creditedSats: number;
|
|
34
|
+
transferId: string;
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* Return the network this provider is configured for.
|
|
38
|
+
*/
|
|
39
|
+
getNetwork(): Network;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=spark-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-provider.d.ts","sourceRoot":"","sources":["../../../src/services/lightning/spark-provider.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAkFvD,qBAAa,sBAAuB,YAAW,iBAAiB;IAE5D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAF1B,OAAO;IAKP;;;;OAIG;WACU,UAAU,CACrB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,sBAAsB,CAAC;IAU5B,UAAU,CACd,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAoC5C,aAAa,CACjB,UAAU,EAAE,MAAM,EAClB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAY7C,UAAU,IAAI,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC;IAO9C,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC;IAIpC,YAAY,CAChB,aAAa,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAiCxD;;OAEG;IACH,UAAU,IAAI,OAAO;CAGtB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spark SDK-backed LightningProvider implementation.
|
|
3
|
+
*
|
|
4
|
+
* Wraps SparkWallet (from @buildonspark/spark-sdk) to satisfy the
|
|
5
|
+
* LightningProvider interface. Auth is handled by the SDK using the user's
|
|
6
|
+
* BIP39 identity key — no API key is required.
|
|
7
|
+
*/
|
|
8
|
+
import { SparkWallet } from "@buildonspark/spark-sdk";
|
|
9
|
+
/**
|
|
10
|
+
* Map aibtc Network to Spark SDK network type.
|
|
11
|
+
*
|
|
12
|
+
* Spark publicly supports MAINNET and REGTEST. REGTEST is a Spark-internal
|
|
13
|
+
* regtest chain — its `bcrt1...` deposit addresses cannot interoperate with
|
|
14
|
+
* Bitcoin testnet's `tb1...` addresses, so silently mapping aibtc's testnet
|
|
15
|
+
* to Spark's REGTEST would break `lightning_fund_from_btc` (the L1 testnet
|
|
16
|
+
* tx is sent to a different chain than the deposit address it's funding).
|
|
17
|
+
*
|
|
18
|
+
* Until Spark ships a public Bitcoin-testnet environment, reject testnet at
|
|
19
|
+
* the boundary with a clear error rather than silently misbehaving.
|
|
20
|
+
*/
|
|
21
|
+
function toSparkNetwork(network) {
|
|
22
|
+
if (network === "mainnet")
|
|
23
|
+
return "MAINNET";
|
|
24
|
+
throw new Error("Lightning is currently only supported on mainnet. Spark does not have a public Bitcoin testnet " +
|
|
25
|
+
"environment, and Spark REGTEST cannot interoperate with Bitcoin testnet. " +
|
|
26
|
+
"Switch NETWORK=mainnet (uses real BTC) or wait for Spark testnet support.");
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Default max routing fee used when the caller does not pass one.
|
|
30
|
+
* 10 sats covers typical small-invoice routing without being permissive.
|
|
31
|
+
*/
|
|
32
|
+
const DEFAULT_MAX_FEE_SATS = 10;
|
|
33
|
+
/**
|
|
34
|
+
* Convert a Spark `CurrencyAmount` to whole satoshis.
|
|
35
|
+
*
|
|
36
|
+
* Sub-satoshi units (MILLISATOSHI, NANOBITCOIN) are floored — the L402 / fee
|
|
37
|
+
* reporting surface deals in whole sats. Fiat units (USD, MXN, PHP, EUR) and
|
|
38
|
+
* the SDK's FUTURE_VALUE sentinel must never appear on a wallet operation; if
|
|
39
|
+
* they do, that is an SDK contract violation we want to surface rather than
|
|
40
|
+
* silently coerce.
|
|
41
|
+
*/
|
|
42
|
+
function currencyAmountToSats(amount) {
|
|
43
|
+
const { originalValue: value, originalUnit: unit } = amount;
|
|
44
|
+
switch (unit) {
|
|
45
|
+
case "SATOSHI":
|
|
46
|
+
return value;
|
|
47
|
+
case "MILLISATOSHI":
|
|
48
|
+
return Math.floor(value / 1000);
|
|
49
|
+
case "BITCOIN":
|
|
50
|
+
return value * 100_000_000;
|
|
51
|
+
case "MILLIBITCOIN":
|
|
52
|
+
return value * 100_000;
|
|
53
|
+
case "MICROBITCOIN":
|
|
54
|
+
return value * 100;
|
|
55
|
+
case "NANOBITCOIN":
|
|
56
|
+
return Math.floor(value / 10);
|
|
57
|
+
case "USD":
|
|
58
|
+
case "MXN":
|
|
59
|
+
case "PHP":
|
|
60
|
+
case "EUR":
|
|
61
|
+
case "FUTURE_VALUE":
|
|
62
|
+
throw new Error(`Spark returned a CurrencyAmount denominated in ${unit}; expected a Bitcoin unit. ` +
|
|
63
|
+
`This is an SDK contract violation for a wallet-operation amount.`);
|
|
64
|
+
default:
|
|
65
|
+
throw new Error(`Unknown Spark CurrencyUnit "${unit}"; refusing to coerce to sats.`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export class SparkLightningProvider {
|
|
69
|
+
wallet;
|
|
70
|
+
network;
|
|
71
|
+
constructor(wallet, network) {
|
|
72
|
+
this.wallet = wallet;
|
|
73
|
+
this.network = network;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Initialize a Spark-backed provider from a mnemonic.
|
|
77
|
+
* The wallet itself is managed by the lightning-manager singleton — this
|
|
78
|
+
* factory is the only place the SDK is touched directly.
|
|
79
|
+
*/
|
|
80
|
+
static async initialize(mnemonic, network) {
|
|
81
|
+
const { wallet } = await SparkWallet.initialize({
|
|
82
|
+
mnemonicOrSeed: mnemonic,
|
|
83
|
+
options: {
|
|
84
|
+
network: toSparkNetwork(network),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
return new SparkLightningProvider(wallet, network);
|
|
88
|
+
}
|
|
89
|
+
async payInvoice(bolt11, maxFeeSats) {
|
|
90
|
+
const result = await this.wallet.payLightningInvoice({
|
|
91
|
+
invoice: bolt11,
|
|
92
|
+
maxFeeSats: maxFeeSats ?? DEFAULT_MAX_FEE_SATS,
|
|
93
|
+
});
|
|
94
|
+
// payLightningInvoice returns LightningSendRequest | WalletTransfer.
|
|
95
|
+
// A successful Lightning payment yields a LightningSendRequest with a
|
|
96
|
+
// paymentPreimage — Spark-routed fallbacks (WalletTransfer) have no
|
|
97
|
+
// preimage and can't satisfy an L402 challenge.
|
|
98
|
+
const sendRequest = result;
|
|
99
|
+
if (!sendRequest.paymentPreimage) {
|
|
100
|
+
throw new Error("Lightning payment did not return a preimage (may have routed over Spark instead of Lightning). " +
|
|
101
|
+
"L402 requires a Lightning preimage for authentication.");
|
|
102
|
+
}
|
|
103
|
+
// LightningSendRequest.fee is a CurrencyAmount whose originalUnit can be
|
|
104
|
+
// any of {SATOSHI, MILLISATOSHI, BITCOIN, ...}. Reading originalValue
|
|
105
|
+
// blindly as sats mis-reports fees by orders of magnitude on non-SATOSHI
|
|
106
|
+
// units — pass through the helper so the unit is always honored.
|
|
107
|
+
const feesPaid = sendRequest.fee
|
|
108
|
+
? currencyAmountToSats(sendRequest.fee)
|
|
109
|
+
: 0;
|
|
110
|
+
return {
|
|
111
|
+
preimage: sendRequest.paymentPreimage,
|
|
112
|
+
feesPaid,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async createInvoice(amountSats, memo) {
|
|
116
|
+
const receiveRequest = await this.wallet.createLightningInvoice({
|
|
117
|
+
amountSats,
|
|
118
|
+
memo,
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
bolt11: receiveRequest.invoice.encodedInvoice,
|
|
122
|
+
paymentHash: receiveRequest.invoice.paymentHash,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
async getBalance() {
|
|
126
|
+
const balance = await this.wallet.getBalance();
|
|
127
|
+
return {
|
|
128
|
+
balanceSats: Number(balance.satsBalance.available),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async getDepositAddress() {
|
|
132
|
+
return this.wallet.getStaticDepositAddress();
|
|
133
|
+
}
|
|
134
|
+
async claimDeposit(transactionId, outputIndex) {
|
|
135
|
+
// Canonical Spark deposit-claim flow per docs.spark.money:
|
|
136
|
+
// 1. Fetch the SSP-signed quote (returns creditAmountSats + signature).
|
|
137
|
+
// 2. Submit the quote's signature with the claim.
|
|
138
|
+
//
|
|
139
|
+
// The SDK's ClaimStaticDepositOutput is exactly { transferId: string },
|
|
140
|
+
// so we keep the quote's creditAmountSats around to surface back to the
|
|
141
|
+
// caller — this also matches what the SSP actually committed to.
|
|
142
|
+
const quote = await this.wallet.getClaimStaticDepositQuote(transactionId, outputIndex);
|
|
143
|
+
const result = await this.wallet.claimStaticDeposit({
|
|
144
|
+
transactionId,
|
|
145
|
+
creditAmountSats: quote.creditAmountSats,
|
|
146
|
+
sspSignature: quote.signature,
|
|
147
|
+
outputIndex,
|
|
148
|
+
});
|
|
149
|
+
if (!result) {
|
|
150
|
+
throw new Error(`Claim failed: SSP returned no result for transaction ${transactionId}. ` +
|
|
151
|
+
`The deposit may not have enough confirmations yet (3 required) or has already been claimed.`);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
creditedSats: quote.creditAmountSats,
|
|
155
|
+
transferId: result.transferId,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Return the network this provider is configured for.
|
|
160
|
+
*/
|
|
161
|
+
getNetwork() {
|
|
162
|
+
return this.network;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=spark-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spark-provider.js","sourceRoot":"","sources":["../../../src/services/lightning/spark-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightning wallet manager — singleton that parallels WalletManager.
|
|
3
|
+
*
|
|
4
|
+
* Stores an encrypted Lightning mnemonic at ~/.aibtc/lightning/keystore.json
|
|
5
|
+
* and holds the initialized Spark-backed LightningProvider in-memory while
|
|
6
|
+
* the wallet is unlocked.
|
|
7
|
+
*/
|
|
8
|
+
import { type Network } from "../config/networks.js";
|
|
9
|
+
import type { LightningProvider } from "./lightning/provider.js";
|
|
10
|
+
export interface LightningCreateResult {
|
|
11
|
+
walletId: string;
|
|
12
|
+
mnemonic: string;
|
|
13
|
+
depositAddress: string;
|
|
14
|
+
lightningAddress: string | null;
|
|
15
|
+
}
|
|
16
|
+
export interface LightningImportResult {
|
|
17
|
+
walletId: string;
|
|
18
|
+
depositAddress: string;
|
|
19
|
+
lightningAddress: string | null;
|
|
20
|
+
}
|
|
21
|
+
export interface LightningUnlockResult {
|
|
22
|
+
walletId: string;
|
|
23
|
+
balanceSats: number;
|
|
24
|
+
lightningAddress: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface LightningStatus {
|
|
27
|
+
locked: boolean;
|
|
28
|
+
walletId?: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
network?: Network;
|
|
31
|
+
lightningAddress?: string | null;
|
|
32
|
+
depositAddress?: string;
|
|
33
|
+
balanceSats?: number;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Singleton manager for the embedded Lightning wallet.
|
|
37
|
+
*/
|
|
38
|
+
declare class LightningManager {
|
|
39
|
+
private static instance;
|
|
40
|
+
private session;
|
|
41
|
+
private constructor();
|
|
42
|
+
static getInstance(): LightningManager;
|
|
43
|
+
/**
|
|
44
|
+
* Ensure the ~/.aibtc/lightning directory exists with 0700 perms.
|
|
45
|
+
*/
|
|
46
|
+
private ensureStorage;
|
|
47
|
+
private keystoreExists;
|
|
48
|
+
private readKeystore;
|
|
49
|
+
private writeKeystore;
|
|
50
|
+
/**
|
|
51
|
+
* Store a mnemonic (shared logic for create/import).
|
|
52
|
+
*
|
|
53
|
+
* Initialize the Spark provider FIRST so connectivity / SDK validation
|
|
54
|
+
* failures don't leave behind an encrypted keystore that blocks future
|
|
55
|
+
* `lightning_create` / `lightning_import` calls (keystoreExists() short-
|
|
56
|
+
* circuits both paths). Only after the provider is up do we persist the
|
|
57
|
+
* keystore and establish the session.
|
|
58
|
+
*/
|
|
59
|
+
private storeWallet;
|
|
60
|
+
/**
|
|
61
|
+
* Create a new Lightning wallet with a fresh BIP39 mnemonic.
|
|
62
|
+
*/
|
|
63
|
+
createWallet(password: string, name: string, network?: Network): Promise<LightningCreateResult>;
|
|
64
|
+
/**
|
|
65
|
+
* Import an existing Lightning wallet from a BIP39 mnemonic.
|
|
66
|
+
*/
|
|
67
|
+
importWallet(mnemonic: string, password: string, name: string, network?: Network): Promise<LightningImportResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Unlock the Lightning wallet by decrypting the keystore and initializing
|
|
70
|
+
* a SparkWallet session in-memory.
|
|
71
|
+
*/
|
|
72
|
+
unlock(password: string): Promise<LightningUnlockResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Clear the in-memory session.
|
|
75
|
+
*/
|
|
76
|
+
lock(): void;
|
|
77
|
+
/**
|
|
78
|
+
* Return the active LightningProvider, or null if locked.
|
|
79
|
+
*/
|
|
80
|
+
getProvider(): LightningProvider | null;
|
|
81
|
+
/**
|
|
82
|
+
* Is a Lightning wallet currently unlocked?
|
|
83
|
+
*/
|
|
84
|
+
isUnlocked(): boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Lightweight status snapshot for lightning_status.
|
|
87
|
+
*/
|
|
88
|
+
getStatus(): Promise<LightningStatus>;
|
|
89
|
+
/**
|
|
90
|
+
* Provider.getLightningAddress may be unimplemented — normalize to null.
|
|
91
|
+
*/
|
|
92
|
+
private safeLightningAddress;
|
|
93
|
+
}
|
|
94
|
+
export declare function getLightningManager(): LightningManager;
|
|
95
|
+
export {};
|
|
96
|
+
//# sourceMappingURL=lightning-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightning-manager.d.ts","sourceRoot":"","sources":["../../src/services/lightning-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkBH,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AA2BjE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,cAAM,gBAAgB;IACpB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAmB;IAC1C,OAAO,CAAC,OAAO,CAAiC;IAEhD,OAAO;IAEP,MAAM,CAAC,WAAW,IAAI,gBAAgB;IAOtC;;OAEG;YACW,aAAa;YAIb,cAAc;YASd,YAAY;YAKZ,aAAa;IAS3B;;;;;;;;OAQG;YACW,WAAW;IAmCzB;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,qBAAqB,CAAC;IA2BjC;;OAEG;IACG,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,qBAAqB,CAAC;IA8BjC;;;OAGG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAsC9D;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,WAAW,IAAI,iBAAiB,GAAG,IAAI;IAIvC;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,eAAe,CAAC;IAgC3C;;OAEG;YACW,oBAAoB;CAMnC;AAED,wBAAgB,mBAAmB,IAAI,gBAAgB,CAEtD"}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightning wallet manager — singleton that parallels WalletManager.
|
|
3
|
+
*
|
|
4
|
+
* Stores an encrypted Lightning mnemonic at ~/.aibtc/lightning/keystore.json
|
|
5
|
+
* and holds the initialized Spark-backed LightningProvider in-memory while
|
|
6
|
+
* the wallet is unlocked.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "fs/promises";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import os from "os";
|
|
11
|
+
import { generateMnemonic, validateMnemonic } from "@scure/bip39";
|
|
12
|
+
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
13
|
+
import { encrypt, decrypt, generateWalletId, } from "../utils/index.js";
|
|
14
|
+
import { InvalidPasswordError, InvalidMnemonicError, WalletError, } from "../utils/errors.js";
|
|
15
|
+
import { NETWORK } from "../config/networks.js";
|
|
16
|
+
import { SparkLightningProvider } from "./lightning/spark-provider.js";
|
|
17
|
+
const LIGHTNING_DIR = path.join(os.homedir(), ".aibtc", "lightning");
|
|
18
|
+
const KEYSTORE_FILE = path.join(LIGHTNING_DIR, "keystore.json");
|
|
19
|
+
/**
|
|
20
|
+
* Singleton manager for the embedded Lightning wallet.
|
|
21
|
+
*/
|
|
22
|
+
class LightningManager {
|
|
23
|
+
static instance;
|
|
24
|
+
session = null;
|
|
25
|
+
constructor() { }
|
|
26
|
+
static getInstance() {
|
|
27
|
+
if (!LightningManager.instance) {
|
|
28
|
+
LightningManager.instance = new LightningManager();
|
|
29
|
+
}
|
|
30
|
+
return LightningManager.instance;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Ensure the ~/.aibtc/lightning directory exists with 0700 perms.
|
|
34
|
+
*/
|
|
35
|
+
async ensureStorage() {
|
|
36
|
+
await fs.mkdir(LIGHTNING_DIR, { recursive: true, mode: 0o700 });
|
|
37
|
+
}
|
|
38
|
+
async keystoreExists() {
|
|
39
|
+
try {
|
|
40
|
+
await fs.access(KEYSTORE_FILE);
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async readKeystore() {
|
|
48
|
+
const content = await fs.readFile(KEYSTORE_FILE, "utf8");
|
|
49
|
+
return JSON.parse(content);
|
|
50
|
+
}
|
|
51
|
+
async writeKeystore(keystore) {
|
|
52
|
+
await this.ensureStorage();
|
|
53
|
+
const tempFile = `${KEYSTORE_FILE}.tmp`;
|
|
54
|
+
await fs.writeFile(tempFile, JSON.stringify(keystore, null, 2), {
|
|
55
|
+
mode: 0o600,
|
|
56
|
+
});
|
|
57
|
+
await fs.rename(tempFile, KEYSTORE_FILE);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Store a mnemonic (shared logic for create/import).
|
|
61
|
+
*
|
|
62
|
+
* Initialize the Spark provider FIRST so connectivity / SDK validation
|
|
63
|
+
* failures don't leave behind an encrypted keystore that blocks future
|
|
64
|
+
* `lightning_create` / `lightning_import` calls (keystoreExists() short-
|
|
65
|
+
* circuits both paths). Only after the provider is up do we persist the
|
|
66
|
+
* keystore and establish the session.
|
|
67
|
+
*/
|
|
68
|
+
async storeWallet(name, mnemonic, password, network) {
|
|
69
|
+
// 1. Bring up the Spark provider — validates the mnemonic + connectivity.
|
|
70
|
+
// If this throws, no keystore is written and the user can retry cleanly.
|
|
71
|
+
const provider = await SparkLightningProvider.initialize(mnemonic, network);
|
|
72
|
+
// 2. Persist the keystore now that we know the provider is functional.
|
|
73
|
+
const encrypted = await encrypt(mnemonic, password);
|
|
74
|
+
const walletId = generateWalletId();
|
|
75
|
+
const keystore = {
|
|
76
|
+
version: 1,
|
|
77
|
+
walletId,
|
|
78
|
+
name,
|
|
79
|
+
network,
|
|
80
|
+
encrypted,
|
|
81
|
+
createdAt: new Date().toISOString(),
|
|
82
|
+
};
|
|
83
|
+
await this.writeKeystore(keystore);
|
|
84
|
+
// 3. Establish the in-memory session.
|
|
85
|
+
this.session = {
|
|
86
|
+
walletId,
|
|
87
|
+
name,
|
|
88
|
+
network,
|
|
89
|
+
provider,
|
|
90
|
+
};
|
|
91
|
+
return { walletId, provider };
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Create a new Lightning wallet with a fresh BIP39 mnemonic.
|
|
95
|
+
*/
|
|
96
|
+
async createWallet(password, name, network) {
|
|
97
|
+
if (await this.keystoreExists()) {
|
|
98
|
+
throw new WalletError("A Lightning wallet already exists. Use lightning_unlock to access it, or delete ~/.aibtc/lightning/keystore.json to replace it.");
|
|
99
|
+
}
|
|
100
|
+
const mnemonic = generateMnemonic(wordlist, 256);
|
|
101
|
+
const walletNetwork = network || NETWORK;
|
|
102
|
+
const { walletId, provider } = await this.storeWallet(name, mnemonic, password, walletNetwork);
|
|
103
|
+
const depositAddress = await provider.getDepositAddress();
|
|
104
|
+
const lightningAddress = await this.safeLightningAddress(provider);
|
|
105
|
+
return {
|
|
106
|
+
walletId,
|
|
107
|
+
mnemonic,
|
|
108
|
+
depositAddress,
|
|
109
|
+
lightningAddress,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Import an existing Lightning wallet from a BIP39 mnemonic.
|
|
114
|
+
*/
|
|
115
|
+
async importWallet(mnemonic, password, name, network) {
|
|
116
|
+
if (await this.keystoreExists()) {
|
|
117
|
+
throw new WalletError("A Lightning wallet already exists. Use lightning_unlock to access it, or delete ~/.aibtc/lightning/keystore.json to replace it.");
|
|
118
|
+
}
|
|
119
|
+
const normalized = mnemonic.trim().toLowerCase();
|
|
120
|
+
if (!validateMnemonic(normalized, wordlist)) {
|
|
121
|
+
throw new InvalidMnemonicError();
|
|
122
|
+
}
|
|
123
|
+
const walletNetwork = network || NETWORK;
|
|
124
|
+
const { walletId, provider } = await this.storeWallet(name, normalized, password, walletNetwork);
|
|
125
|
+
const depositAddress = await provider.getDepositAddress();
|
|
126
|
+
const lightningAddress = await this.safeLightningAddress(provider);
|
|
127
|
+
return {
|
|
128
|
+
walletId,
|
|
129
|
+
depositAddress,
|
|
130
|
+
lightningAddress,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Unlock the Lightning wallet by decrypting the keystore and initializing
|
|
135
|
+
* a SparkWallet session in-memory.
|
|
136
|
+
*/
|
|
137
|
+
async unlock(password) {
|
|
138
|
+
if (!(await this.keystoreExists())) {
|
|
139
|
+
throw new WalletError("No Lightning wallet found. Use lightning_create or lightning_import to set one up.");
|
|
140
|
+
}
|
|
141
|
+
const keystore = await this.readKeystore();
|
|
142
|
+
let mnemonic;
|
|
143
|
+
try {
|
|
144
|
+
mnemonic = await decrypt(keystore.encrypted, password);
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
throw new InvalidPasswordError();
|
|
148
|
+
}
|
|
149
|
+
const provider = await SparkLightningProvider.initialize(mnemonic, keystore.network);
|
|
150
|
+
this.session = {
|
|
151
|
+
walletId: keystore.walletId,
|
|
152
|
+
name: keystore.name,
|
|
153
|
+
network: keystore.network,
|
|
154
|
+
provider,
|
|
155
|
+
};
|
|
156
|
+
const balance = await provider.getBalance();
|
|
157
|
+
const lightningAddress = await this.safeLightningAddress(provider);
|
|
158
|
+
return {
|
|
159
|
+
walletId: keystore.walletId,
|
|
160
|
+
balanceSats: balance.balanceSats,
|
|
161
|
+
lightningAddress,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Clear the in-memory session.
|
|
166
|
+
*/
|
|
167
|
+
lock() {
|
|
168
|
+
this.session = null;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Return the active LightningProvider, or null if locked.
|
|
172
|
+
*/
|
|
173
|
+
getProvider() {
|
|
174
|
+
return this.session?.provider ?? null;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Is a Lightning wallet currently unlocked?
|
|
178
|
+
*/
|
|
179
|
+
isUnlocked() {
|
|
180
|
+
return this.session !== null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Lightweight status snapshot for lightning_status.
|
|
184
|
+
*/
|
|
185
|
+
async getStatus() {
|
|
186
|
+
if (!this.session) {
|
|
187
|
+
if (!(await this.keystoreExists())) {
|
|
188
|
+
return { locked: true };
|
|
189
|
+
}
|
|
190
|
+
const keystore = await this.readKeystore();
|
|
191
|
+
return {
|
|
192
|
+
locked: true,
|
|
193
|
+
walletId: keystore.walletId,
|
|
194
|
+
name: keystore.name,
|
|
195
|
+
network: keystore.network,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
const { walletId, name, network, provider } = this.session;
|
|
199
|
+
const [balance, depositAddress, lightningAddress] = await Promise.all([
|
|
200
|
+
provider.getBalance(),
|
|
201
|
+
provider.getDepositAddress(),
|
|
202
|
+
this.safeLightningAddress(provider),
|
|
203
|
+
]);
|
|
204
|
+
return {
|
|
205
|
+
locked: false,
|
|
206
|
+
walletId,
|
|
207
|
+
name,
|
|
208
|
+
network,
|
|
209
|
+
balanceSats: balance.balanceSats,
|
|
210
|
+
depositAddress,
|
|
211
|
+
lightningAddress,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Provider.getLightningAddress may be unimplemented — normalize to null.
|
|
216
|
+
*/
|
|
217
|
+
async safeLightningAddress(provider) {
|
|
218
|
+
if (!provider.getLightningAddress)
|
|
219
|
+
return null;
|
|
220
|
+
return provider.getLightningAddress();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
export function getLightningManager() {
|
|
224
|
+
return LightningManager.getInstance();
|
|
225
|
+
}
|
|
226
|
+
//# sourceMappingURL=lightning-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lightning-manager.js","sourceRoot":"","sources":["../../src/services/lightning-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sbtc-deposit.service.d.ts","sourceRoot":"","sources":["../../src/services/sbtc-deposit.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAYH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAMrD;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,aAAc,SAAQ,wBAAwB;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8C;IACxE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEtB,OAAO,EAAE,OAAO;IAS5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;;;;OAKG;YACW,YAAY;IAe1B;;;;;OAKG;IACG,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC;IAQ5C;;;;;;;;;;;;OAYG;IACG,mBAAmB,CACvB,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,YAAY,CAAC,EAAE,MAAM,EACrB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,oBAAoB,CAAC;IAsBhC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,uBAAuB,CAC3B,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,UAAU,CAAC,EAAE,UAAU,EACvB,eAAe,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"sbtc-deposit.service.d.ts","sourceRoot":"","sources":["../../src/services/sbtc-deposit.service.ts"],"names":[],"mappings":"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"}
|