Skip to main content

MuSig2CombineKeys

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!

Source: signrpc/signer.proto

gRPC

rpc MuSig2CombineKeys (MuSig2CombineKeysRequest) returns (MuSig2CombineKeysResponse);

REST

HTTP MethodPath
POST /v2/signer/musig2/combinekeys

Code Samples

const fs = require('fs');
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');

const GRPC_HOST = 'localhost:10009'
const MACAROON_PATH = 'LND_DIR/data/chain/bitcoin/regtest/admin.macaroon'
const TLS_PATH = 'LND_DIR/tls.cert'

const loaderOptions = {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
};
const packageDefinition = protoLoader.loadSync(['lightning.proto', 'signrpc/signer.proto'], loaderOptions);
const signrpc = grpc.loadPackageDefinition(packageDefinition).signrpc;
process.env.GRPC_SSL_CIPHER_SUITES = 'HIGH+ECDSA';
const tlsCert = fs.readFileSync(TLS_PATH);
const sslCreds = grpc.credentials.createSsl(tlsCert);
const macaroon = fs.readFileSync(MACAROON_PATH).toString('hex');
const macaroonCreds = grpc.credentials.createFromMetadataGenerator(function(args, callback) {
let metadata = new grpc.Metadata();
metadata.add('macaroon', macaroon);
callback(null, metadata);
});
let creds = grpc.credentials.combineChannelCredentials(sslCreds, macaroonCreds);
let client = new signrpc.Signer(GRPC_HOST, creds);
let request = {
all_signer_pubkeys: <bytes>,
tweaks: <TweakDesc>,
taproot_tweak: <TaprootTweakDesc>,
};
client.muSig2CombineKeys(request, function(err, response) {
console.log(response);
});
// Console output:
// {
// "combined_key": <bytes>,
// "taproot_internal_key": <bytes>,
// }

Messages

signrpc.MuSig2CombineKeysRequest

Source: signrpc/signer.proto

FieldgRPC TypeREST TypeREST Placement
all_signer_pubkeys
bytes[]arraybody
tweaks
TweakDesc[]arraybody
taproot_tweak
TaprootTweakDescobjectbody

signrpc.MuSig2CombineKeysResponse

Source: signrpc/signer.proto

FieldgRPC TypeREST Type
combined_key
bytesstring
taproot_internal_key
bytesstring

Nested Messages

signrpc.TweakDesc

FieldgRPC TypeREST Type
tweak
bytesstring
is_x_only
boolboolean

signrpc.TaprootTweakDesc

FieldgRPC TypeREST Type
script_root
bytesstring
key_spend_only
boolboolean