lightning-pub/proto/lnd/signer.client.ts
padreug 77e5772afd
Some checks are pending
Docker Compose Actions Workflow / test (push) Waiting to run
feat(extensions): add extension loader infrastructure (#3)
## Summary

- Adds a modular extension system for Lightning.Pub enabling third-party plugins
- Provides isolated SQLite databases per extension for data safety
- Implements ExtensionContext API for accessing Lightning.Pub services (payments, Nostr, storage)
- Supports RPC method registration with automatic namespacing
- Includes HTTP route handling for protocols like LNURL
- Event routing for payment receipts and Nostr events
- Comprehensive documentation with architecture overview and working examples

## Key Components

- `src/extensions/types.ts` - Core extension interfaces
- `src/extensions/loader.ts` - Extension discovery, loading, and lifecycle management
- `src/extensions/context.ts` - Bridge between extensions and Lightning.Pub services
- `src/extensions/database.ts` - SQLite isolation with WAL mode
- `src/extensions/README.md` - Full documentation with examples

## ExtensionContext API

| Method | Description |
|--------|-------------|
| `getApplication()` | Get application info |
| `createInvoice()` | Create Lightning invoice |
| `payInvoice()` | Pay Lightning invoice |
| `getLnurlPayInfo()` | Get LNURL-pay info for a user (enables Lightning Address/zaps) |
| `sendEncryptedDM()` | Send Nostr DM (NIP-44) |
| `publishNostrEvent()` | Publish Nostr event |
| `registerMethod()` | Register RPC method |
| `onPaymentReceived()` | Subscribe to payment callbacks |
| `onNostrEvent()` | Subscribe to Nostr events |

## Test plan

- [x] Review extension loader code for correctness
- [x] Verify TypeScript compilation succeeds
- [x] Test extension discovery from `src/extensions/` directory
- [x] Test RPC method registration and routing
- [x] Test database isolation between extensions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: boufni95 <boufni95@gmail.com>
Co-authored-by: Patrick Mulligan <patjmulligan@protonmail.com>
Reviewed-on: #3
2026-04-02 18:47:55 +00:00

394 lines
20 KiB
TypeScript

// @generated by protobuf-ts 2.11.1
// @generated from protobuf file "signer.proto" (package "signrpc", syntax proto3)
// tslint:disable
import type { RpcTransport } from "@protobuf-ts/runtime-rpc";
import type { ServiceInfo } from "@protobuf-ts/runtime-rpc";
import { Signer } from "./signer.js";
import type { MuSig2CleanupResponse } from "./signer.js";
import type { MuSig2CleanupRequest } from "./signer.js";
import type { MuSig2CombineSigResponse } from "./signer.js";
import type { MuSig2CombineSigRequest } from "./signer.js";
import type { MuSig2SignResponse } from "./signer.js";
import type { MuSig2SignRequest } from "./signer.js";
import type { MuSig2RegisterNoncesResponse } from "./signer.js";
import type { MuSig2RegisterNoncesRequest } from "./signer.js";
import type { MuSig2SessionResponse } from "./signer.js";
import type { MuSig2SessionRequest } from "./signer.js";
import type { MuSig2CombineKeysResponse } from "./signer.js";
import type { MuSig2CombineKeysRequest } from "./signer.js";
import type { SharedKeyResponse } from "./signer.js";
import type { SharedKeyRequest } from "./signer.js";
import type { VerifyMessageResp } from "./signer.js";
import type { VerifyMessageReq } from "./signer.js";
import type { SignMessageResp } from "./signer.js";
import type { SignMessageReq } from "./signer.js";
import type { InputScriptResp } from "./signer.js";
import { stackIntercept } from "@protobuf-ts/runtime-rpc";
import type { SignResp } from "./signer.js";
import type { SignReq } from "./signer.js";
import type { UnaryCall } from "@protobuf-ts/runtime-rpc";
import type { RpcOptions } from "@protobuf-ts/runtime-rpc";
/**
* Signer is a service that gives access to the signing functionality of the
* daemon's wallet.
*
* @generated from protobuf service signrpc.Signer
*/
export interface ISignerClient {
/**
*
* SignOutputRaw is a method that can be used to generated a signature for a
* set of inputs/outputs to a transaction. Each request specifies details
* concerning how the outputs should be signed, which keys they should be
* signed with, and also any optional tweaks. The return value is a fixed
* 64-byte signature (the same format as we use on the wire in Lightning).
*
* If we are unable to sign using the specified keys, then an error will be
* returned.
*
* @generated from protobuf rpc: SignOutputRaw
*/
signOutputRaw(input: SignReq, options?: RpcOptions): UnaryCall<SignReq, SignResp>;
/**
*
* ComputeInputScript generates a complete InputIndex for the passed
* transaction with the signature as defined within the passed SignDescriptor.
* This method should be capable of generating the proper input script for both
* regular p2wkh/p2tr outputs and p2wkh outputs nested within a regular p2sh
* output.
*
* Note that when using this method to sign inputs belonging to the wallet,
* the only items of the SignDescriptor that need to be populated are pkScript
* in the TxOut field, the value in that same field, and finally the input
* index.
*
* @generated from protobuf rpc: ComputeInputScript
*/
computeInputScript(input: SignReq, options?: RpcOptions): UnaryCall<SignReq, InputScriptResp>;
/**
*
* SignMessage signs a message with the key specified in the key locator. The
* returned signature is fixed-size LN wire format encoded.
*
* The main difference to SignMessage in the main RPC is that a specific key is
* used to sign the message instead of the node identity private key.
*
* @generated from protobuf rpc: SignMessage
*/
signMessage(input: SignMessageReq, options?: RpcOptions): UnaryCall<SignMessageReq, SignMessageResp>;
/**
*
* VerifyMessage verifies a signature over a message using the public key
* provided. The signature must be fixed-size LN wire format encoded.
*
* The main difference to VerifyMessage in the main RPC is that the public key
* used to sign the message does not have to be a node known to the network.
*
* @generated from protobuf rpc: VerifyMessage
*/
verifyMessage(input: VerifyMessageReq, options?: RpcOptions): UnaryCall<VerifyMessageReq, VerifyMessageResp>;
/**
*
* DeriveSharedKey returns a shared secret key by performing Diffie-Hellman key
* derivation between the ephemeral public key in the request and the node's
* key specified in the key_desc parameter. Either a key locator or a raw
* public key is expected in the key_desc, if neither is supplied, defaults to
* the node's identity private key:
* P_shared = privKeyNode * ephemeralPubkey
* The resulting shared public key is serialized in the compressed format and
* hashed with sha256, resulting in the final key length of 256bit.
*
* @generated from protobuf rpc: DeriveSharedKey
*/
deriveSharedKey(input: SharedKeyRequest, options?: RpcOptions): UnaryCall<SharedKeyRequest, SharedKeyResponse>;
/**
*
* MuSig2CombineKeys (experimental!) is a stateless helper RPC that can be used
* to calculate the combined MuSig2 public key from a list of all participating
* signers' public keys. This RPC is completely stateless and deterministic and
* does not create any signing session. It can be used to determine the Taproot
* public key that should be put in an on-chain output once all public keys are
* known. A signing session is only needed later when that output should be
* _spent_ again.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CombineKeys
*/
muSig2CombineKeys(input: MuSig2CombineKeysRequest, options?: RpcOptions): UnaryCall<MuSig2CombineKeysRequest, MuSig2CombineKeysResponse>;
/**
*
* MuSig2CreateSession (experimental!) creates a new MuSig2 signing session
* using the local key identified by the key locator. The complete list of all
* public keys of all signing parties must be provided, including the public
* key of the local signing key. If nonces of other parties are already known,
* they can be submitted as well to reduce the number of RPC calls necessary
* later on.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CreateSession
*/
muSig2CreateSession(input: MuSig2SessionRequest, options?: RpcOptions): UnaryCall<MuSig2SessionRequest, MuSig2SessionResponse>;
/**
*
* MuSig2RegisterNonces (experimental!) registers one or more public nonces of
* other signing participants for a session identified by its ID. This RPC can
* be called multiple times until all nonces are registered.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2RegisterNonces
*/
muSig2RegisterNonces(input: MuSig2RegisterNoncesRequest, options?: RpcOptions): UnaryCall<MuSig2RegisterNoncesRequest, MuSig2RegisterNoncesResponse>;
/**
*
* MuSig2Sign (experimental!) creates a partial signature using the local
* signing key that was specified when the session was created. This can only
* be called when all public nonces of all participants are known and have been
* registered with the session. If this node isn't responsible for combining
* all the partial signatures, then the cleanup flag should be set, indicating
* that the session can be removed from memory once the signature was produced.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2Sign
*/
muSig2Sign(input: MuSig2SignRequest, options?: RpcOptions): UnaryCall<MuSig2SignRequest, MuSig2SignResponse>;
/**
*
* MuSig2CombineSig (experimental!) combines the given partial signature(s)
* with the local one, if it already exists. Once a partial signature of all
* participants is registered, the final signature will be combined and
* returned.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CombineSig
*/
muSig2CombineSig(input: MuSig2CombineSigRequest, options?: RpcOptions): UnaryCall<MuSig2CombineSigRequest, MuSig2CombineSigResponse>;
/**
*
* MuSig2Cleanup (experimental!) allows a caller to clean up a session early in
* cases where it's obvious that the signing session won't succeed and the
* resources can be released.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2Cleanup
*/
muSig2Cleanup(input: MuSig2CleanupRequest, options?: RpcOptions): UnaryCall<MuSig2CleanupRequest, MuSig2CleanupResponse>;
}
/**
* Signer is a service that gives access to the signing functionality of the
* daemon's wallet.
*
* @generated from protobuf service signrpc.Signer
*/
export class SignerClient implements ISignerClient, ServiceInfo {
typeName = Signer.typeName;
methods = Signer.methods;
options = Signer.options;
constructor(private readonly _transport: RpcTransport) {
}
/**
*
* SignOutputRaw is a method that can be used to generated a signature for a
* set of inputs/outputs to a transaction. Each request specifies details
* concerning how the outputs should be signed, which keys they should be
* signed with, and also any optional tweaks. The return value is a fixed
* 64-byte signature (the same format as we use on the wire in Lightning).
*
* If we are unable to sign using the specified keys, then an error will be
* returned.
*
* @generated from protobuf rpc: SignOutputRaw
*/
signOutputRaw(input: SignReq, options?: RpcOptions): UnaryCall<SignReq, SignResp> {
const method = this.methods[0], opt = this._transport.mergeOptions(options);
return stackIntercept<SignReq, SignResp>("unary", this._transport, method, opt, input);
}
/**
*
* ComputeInputScript generates a complete InputIndex for the passed
* transaction with the signature as defined within the passed SignDescriptor.
* This method should be capable of generating the proper input script for both
* regular p2wkh/p2tr outputs and p2wkh outputs nested within a regular p2sh
* output.
*
* Note that when using this method to sign inputs belonging to the wallet,
* the only items of the SignDescriptor that need to be populated are pkScript
* in the TxOut field, the value in that same field, and finally the input
* index.
*
* @generated from protobuf rpc: ComputeInputScript
*/
computeInputScript(input: SignReq, options?: RpcOptions): UnaryCall<SignReq, InputScriptResp> {
const method = this.methods[1], opt = this._transport.mergeOptions(options);
return stackIntercept<SignReq, InputScriptResp>("unary", this._transport, method, opt, input);
}
/**
*
* SignMessage signs a message with the key specified in the key locator. The
* returned signature is fixed-size LN wire format encoded.
*
* The main difference to SignMessage in the main RPC is that a specific key is
* used to sign the message instead of the node identity private key.
*
* @generated from protobuf rpc: SignMessage
*/
signMessage(input: SignMessageReq, options?: RpcOptions): UnaryCall<SignMessageReq, SignMessageResp> {
const method = this.methods[2], opt = this._transport.mergeOptions(options);
return stackIntercept<SignMessageReq, SignMessageResp>("unary", this._transport, method, opt, input);
}
/**
*
* VerifyMessage verifies a signature over a message using the public key
* provided. The signature must be fixed-size LN wire format encoded.
*
* The main difference to VerifyMessage in the main RPC is that the public key
* used to sign the message does not have to be a node known to the network.
*
* @generated from protobuf rpc: VerifyMessage
*/
verifyMessage(input: VerifyMessageReq, options?: RpcOptions): UnaryCall<VerifyMessageReq, VerifyMessageResp> {
const method = this.methods[3], opt = this._transport.mergeOptions(options);
return stackIntercept<VerifyMessageReq, VerifyMessageResp>("unary", this._transport, method, opt, input);
}
/**
*
* DeriveSharedKey returns a shared secret key by performing Diffie-Hellman key
* derivation between the ephemeral public key in the request and the node's
* key specified in the key_desc parameter. Either a key locator or a raw
* public key is expected in the key_desc, if neither is supplied, defaults to
* the node's identity private key:
* P_shared = privKeyNode * ephemeralPubkey
* The resulting shared public key is serialized in the compressed format and
* hashed with sha256, resulting in the final key length of 256bit.
*
* @generated from protobuf rpc: DeriveSharedKey
*/
deriveSharedKey(input: SharedKeyRequest, options?: RpcOptions): UnaryCall<SharedKeyRequest, SharedKeyResponse> {
const method = this.methods[4], opt = this._transport.mergeOptions(options);
return stackIntercept<SharedKeyRequest, SharedKeyResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2CombineKeys (experimental!) is a stateless helper RPC that can be used
* to calculate the combined MuSig2 public key from a list of all participating
* signers' public keys. This RPC is completely stateless and deterministic and
* does not create any signing session. It can be used to determine the Taproot
* public key that should be put in an on-chain output once all public keys are
* known. A signing session is only needed later when that output should be
* _spent_ again.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CombineKeys
*/
muSig2CombineKeys(input: MuSig2CombineKeysRequest, options?: RpcOptions): UnaryCall<MuSig2CombineKeysRequest, MuSig2CombineKeysResponse> {
const method = this.methods[5], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2CombineKeysRequest, MuSig2CombineKeysResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2CreateSession (experimental!) creates a new MuSig2 signing session
* using the local key identified by the key locator. The complete list of all
* public keys of all signing parties must be provided, including the public
* key of the local signing key. If nonces of other parties are already known,
* they can be submitted as well to reduce the number of RPC calls necessary
* later on.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CreateSession
*/
muSig2CreateSession(input: MuSig2SessionRequest, options?: RpcOptions): UnaryCall<MuSig2SessionRequest, MuSig2SessionResponse> {
const method = this.methods[6], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2SessionRequest, MuSig2SessionResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2RegisterNonces (experimental!) registers one or more public nonces of
* other signing participants for a session identified by its ID. This RPC can
* be called multiple times until all nonces are registered.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2RegisterNonces
*/
muSig2RegisterNonces(input: MuSig2RegisterNoncesRequest, options?: RpcOptions): UnaryCall<MuSig2RegisterNoncesRequest, MuSig2RegisterNoncesResponse> {
const method = this.methods[7], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2RegisterNoncesRequest, MuSig2RegisterNoncesResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2Sign (experimental!) creates a partial signature using the local
* signing key that was specified when the session was created. This can only
* be called when all public nonces of all participants are known and have been
* registered with the session. If this node isn't responsible for combining
* all the partial signatures, then the cleanup flag should be set, indicating
* that the session can be removed from memory once the signature was produced.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2Sign
*/
muSig2Sign(input: MuSig2SignRequest, options?: RpcOptions): UnaryCall<MuSig2SignRequest, MuSig2SignResponse> {
const method = this.methods[8], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2SignRequest, MuSig2SignResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2CombineSig (experimental!) combines the given partial signature(s)
* with the local one, if it already exists. Once a partial signature of all
* participants is registered, the final signature will be combined and
* returned.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2CombineSig
*/
muSig2CombineSig(input: MuSig2CombineSigRequest, options?: RpcOptions): UnaryCall<MuSig2CombineSigRequest, MuSig2CombineSigResponse> {
const method = this.methods[9], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2CombineSigRequest, MuSig2CombineSigResponse>("unary", this._transport, method, opt, input);
}
/**
*
* MuSig2Cleanup (experimental!) allows a caller to clean up a session early in
* cases where it's obvious that the signing session won't succeed and the
* resources can be released.
*
* NOTE: The MuSig2 BIP is not final yet and therefore this API must be
* considered to be HIGHLY EXPERIMENTAL and subject to change in upcoming
* releases. Backward compatibility is not guaranteed!
*
* @generated from protobuf rpc: MuSig2Cleanup
*/
muSig2Cleanup(input: MuSig2CleanupRequest, options?: RpcOptions): UnaryCall<MuSig2CleanupRequest, MuSig2CleanupResponse> {
const method = this.methods[10], opt = this._transport.mergeOptions(options);
return stackIntercept<MuSig2CleanupRequest, MuSig2CleanupResponse>("unary", this._transport, method, opt, input);
}
}