walletrpc: add ImportTapscript RPC

This commit is contained in:
Oliver Gugger 2022-07-29 18:20:09 +02:00
parent db73e640d9
commit 74fbd61d5f
No known key found for this signature in database
GPG Key ID: 8E4256593F177720
8 changed files with 1465 additions and 535 deletions

File diff suppressed because it is too large Load Diff

View File

@ -430,6 +430,40 @@ func local_request_WalletKit_ImportPublicKey_0(ctx context.Context, marshaler ru
}
func request_WalletKit_ImportTapscript_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ImportTapscriptRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.ImportTapscript(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_WalletKit_ImportTapscript_0(ctx context.Context, marshaler runtime.Marshaler, server WalletKitServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq ImportTapscriptRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.ImportTapscript(ctx, &protoReq)
return msg, metadata, err
}
func request_WalletKit_PublishTransaction_0(ctx context.Context, marshaler runtime.Marshaler, client WalletKitClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Transaction
var metadata runtime.ServerMetadata
@ -1056,6 +1090,29 @@ func RegisterWalletKitHandlerServer(ctx context.Context, mux *runtime.ServeMux,
})
mux.Handle("POST", pattern_WalletKit_ImportTapscript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/walletrpc.WalletKit/ImportTapscript", runtime.WithHTTPPathPattern("/v2/wallet/tapscript/import"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WalletKit_ImportTapscript_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WalletKit_ImportTapscript_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_WalletKit_PublishTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -1567,6 +1624,26 @@ func RegisterWalletKitHandlerClient(ctx context.Context, mux *runtime.ServeMux,
})
mux.Handle("POST", pattern_WalletKit_ImportTapscript_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/walletrpc.WalletKit/ImportTapscript", runtime.WithHTTPPathPattern("/v2/wallet/tapscript/import"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WalletKit_ImportTapscript_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WalletKit_ImportTapscript_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
mux.Handle("POST", pattern_WalletKit_PublishTransaction_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
@ -1795,6 +1872,8 @@ var (
pattern_WalletKit_ImportPublicKey_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "wallet", "key", "import"}, ""))
pattern_WalletKit_ImportTapscript_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"v2", "wallet", "tapscript", "import"}, ""))
pattern_WalletKit_PublishTransaction_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "wallet", "tx"}, ""))
pattern_WalletKit_SendOutputs_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v2", "wallet", "send"}, ""))
@ -1841,6 +1920,8 @@ var (
forward_WalletKit_ImportPublicKey_0 = runtime.ForwardResponseMessage
forward_WalletKit_ImportTapscript_0 = runtime.ForwardResponseMessage
forward_WalletKit_PublishTransaction_0 = runtime.ForwardResponseMessage
forward_WalletKit_SendOutputs_0 = runtime.ForwardResponseMessage

View File

@ -324,6 +324,31 @@ func RegisterWalletKitJSONCallbacks(registry map[string]func(ctx context.Context
callback(string(respBytes), nil)
}
registry["walletrpc.WalletKit.ImportTapscript"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {
req := &ImportTapscriptRequest{}
err := marshaler.Unmarshal([]byte(reqJSON), req)
if err != nil {
callback("", err)
return
}
client := NewWalletKitClient(conn)
resp, err := client.ImportTapscript(ctx, req)
if err != nil {
callback("", err)
return
}
respBytes, err := marshaler.Marshal(resp)
if err != nil {
callback("", err)
return
}
callback(string(respBytes), nil)
}
registry["walletrpc.WalletKit.PublishTransaction"] = func(ctx context.Context,
conn *grpc.ClientConn, reqJSON string, callback func(string, error)) {

View File

@ -107,7 +107,11 @@ service WalletKit {
rpc ImportAccount (ImportAccountRequest) returns (ImportAccountResponse);
/*
ImportPublicKey imports a public key as watch-only into the wallet.
ImportPublicKey imports a public key as watch-only into the wallet. The
public key is converted into a simple address of the given type and that
address script is watched on chain. For Taproot keys, this will only watch
the BIP-0086 style output script. Use ImportTapscript for more advanced key
spend or script spend outputs.
NOTE: Events (deposits/spends) for a key will only be detected by lnd if
they happen after the import. Rescans to detect past events will be
@ -116,6 +120,22 @@ service WalletKit {
rpc ImportPublicKey (ImportPublicKeyRequest)
returns (ImportPublicKeyResponse);
/*
ImportTapscript imports a Taproot script and internal key and adds the
resulting Taproot output key as a watch-only output script into the wallet.
For BIP-0086 style Taproot keys (no root hash commitment and no script spend
path) use ImportPublicKey.
NOTE: Events (deposits/spends) for a key will only be detected by lnd if
they happen after the import. Rescans to detect past events will be
supported later on.
NOTE: Taproot keys imported through this RPC currently _cannot_ be used for
funding PSBTs. Only tracking the balance and UTXOs is currently supported.
*/
rpc ImportTapscript (ImportTapscriptRequest)
returns (ImportTapscriptResponse);
/*
PublishTransaction attempts to publish the passed transaction to the
network. Once this returns without an error, the wallet will continually
@ -541,6 +561,77 @@ message ImportPublicKeyRequest {
message ImportPublicKeyResponse {
}
message ImportTapscriptRequest {
/*
The internal public key, serialized as 32-byte x-only public key.
*/
bytes internal_public_key = 1;
oneof script {
/*
The full script tree with all individual leaves is known and the root
hash can be constructed from the full tree directly.
*/
TapscriptFullTree full_tree = 2;
/*
Only a single script leaf is known. To construct the root hash, the full
inclusion proof must also be provided.
*/
TapscriptPartialReveal partial_reveal = 3;
/*
Only the root hash of the Taproot script tree (or other form of Taproot
commitment) is known.
*/
bytes root_hash_only = 4;
/*
Only the final, tweaked Taproot key is known and no additional
information about the internal key or type of tweak that was used to
derive it. When this is set, the wallet treats the key in
internal_public_key as the Taproot key directly. This can be useful for
tracking arbitrary Taproot outputs without the goal of ever being able
to spend from them through the internal wallet.
*/
bool full_key_only = 5;
}
}
message TapscriptFullTree {
/*
The complete, ordered list of all tap leaves of the tree.
*/
repeated TapLeaf all_leaves = 1;
}
message TapLeaf {
// The leaf version. Should be 0xc0 (192) in case of a SegWit v1 script.
uint32 leaf_version = 1;
// The script of the tap leaf.
bytes script = 2;
}
message TapscriptPartialReveal {
// The tap leaf that is known and will be revealed.
TapLeaf revealed_leaf = 1;
// The BIP-0341 serialized inclusion proof that is required to prove that
// the revealed leaf is part of the tree. This contains 0..n blocks of 32
// bytes. If the tree only contained a single leaf (which is the revealed
// leaf), this can be empty.
bytes full_inclusion_proof = 2;
}
message ImportTapscriptResponse {
/*
The resulting pay-to-Taproot address that represents the imported internal
key with the script committed to it.
*/
string p2tr_address = 1;
}
message Transaction {
/*
The raw serialized transaction.

View File

@ -271,7 +271,7 @@
},
"/v2/wallet/key/import": {
"post": {
"summary": "ImportPublicKey imports a public key as watch-only into the wallet.",
"summary": "ImportPublicKey imports a public key as watch-only into the wallet. The\npublic key is converted into a simple address of the given type and that\naddress script is watched on chain. For Taproot keys, this will only watch\nthe BIP-0086 style output script. Use ImportTapscript for more advanced key\nspend or script spend outputs.",
"description": "NOTE: Events (deposits/spends) for a key will only be detected by lnd if\nthey happen after the import. Rescans to detect past events will be\nsupported later on.",
"operationId": "WalletKit_ImportPublicKey",
"responses": {
@ -560,6 +560,40 @@
]
}
},
"/v2/wallet/tapscript/import": {
"post": {
"summary": "ImportTapscript imports a Taproot script and internal key and adds the\nresulting Taproot output key as a watch-only output script into the wallet.\nFor BIP-0086 style Taproot keys (no root hash commitment and no script spend\npath) use ImportPublicKey.",
"description": "NOTE: Events (deposits/spends) for a key will only be detected by lnd if\nthey happen after the import. Rescans to detect past events will be\nsupported later on.\n\nNOTE: Taproot keys imported through this RPC currently _cannot_ be used for\nfunding PSBTs. Only tracking the balance and UTXOs is currently supported.",
"operationId": "WalletKit_ImportTapscript",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/walletrpcImportTapscriptResponse"
}
},
"default": {
"description": "An unexpected error response.",
"schema": {
"$ref": "#/definitions/rpcStatus"
}
}
},
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/walletrpcImportTapscriptRequest"
}
}
],
"tags": [
"WalletKit"
]
}
},
"/v2/wallet/tx": {
"post": {
"summary": "PublishTransaction attempts to publish the passed transaction to the\nnetwork. Once this returns without an error, the wallet will continually\nattempt to re-broadcast the transaction on start up, until it enters the\nchain.",
@ -1352,6 +1386,42 @@
"walletrpcImportPublicKeyResponse": {
"type": "object"
},
"walletrpcImportTapscriptRequest": {
"type": "object",
"properties": {
"internal_public_key": {
"type": "string",
"format": "byte",
"description": "The internal public key, serialized as 32-byte x-only public key."
},
"full_tree": {
"$ref": "#/definitions/walletrpcTapscriptFullTree",
"description": "The full script tree with all individual leaves is known and the root\nhash can be constructed from the full tree directly."
},
"partial_reveal": {
"$ref": "#/definitions/walletrpcTapscriptPartialReveal",
"description": "Only a single script leaf is known. To construct the root hash, the full\ninclusion proof must also be provided."
},
"root_hash_only": {
"type": "string",
"format": "byte",
"description": "Only the root hash of the Taproot script tree (or other form of Taproot\ncommitment) is known."
},
"full_key_only": {
"type": "boolean",
"description": "Only the final, tweaked Taproot key is known and no additional\ninformation about the internal key or type of tweak that was used to\nderive it. When this is set, the wallet treats the key in\ninternal_public_key as the Taproot key directly. This can be useful for\ntracking arbitrary Taproot outputs without the goal of ever being able\nto spend from them through the internal wallet."
}
}
},
"walletrpcImportTapscriptResponse": {
"type": "object",
"properties": {
"p2tr_address": {
"type": "string",
"description": "The resulting pay-to-Taproot address that represents the imported internal\nkey with the script committed to it."
}
}
},
"walletrpcKeyReq": {
"type": "object",
"properties": {
@ -1671,6 +1741,47 @@
}
}
},
"walletrpcTapLeaf": {
"type": "object",
"properties": {
"leaf_version": {
"type": "integer",
"format": "int64",
"description": "The leaf version. Should be 0xc0 (192) in case of a SegWit v1 script."
},
"script": {
"type": "string",
"format": "byte",
"description": "The script of the tap leaf."
}
}
},
"walletrpcTapscriptFullTree": {
"type": "object",
"properties": {
"all_leaves": {
"type": "array",
"items": {
"$ref": "#/definitions/walletrpcTapLeaf"
},
"description": "The complete, ordered list of all tap leaves of the tree."
}
}
},
"walletrpcTapscriptPartialReveal": {
"type": "object",
"properties": {
"revealed_leaf": {
"$ref": "#/definitions/walletrpcTapLeaf",
"description": "The tap leaf that is known and will be revealed."
},
"full_inclusion_proof": {
"type": "string",
"format": "byte",
"description": "The BIP-0341 serialized inclusion proof that is required to prove that\nthe revealed leaf is part of the tree. This contains 0..n blocks of 32\nbytes. If the tree only contained a single leaf (which is the revealed\nleaf), this can be empty."
}
}
},
"walletrpcTransaction": {
"type": "object",
"properties": {

View File

@ -23,6 +23,9 @@ http:
- selector: walletrpc.WalletKit.ImportPublicKey
post: "/v2/wallet/key/import"
body: "*"
- selector: walletrpc.WalletKit.ImportTapscript
post: "/v2/wallet/tapscript/import"
body: "*"
- selector: walletrpc.WalletKit.NextAddr
post: "/v2/wallet/address/next"
body: "*"

View File

@ -81,12 +81,28 @@ type WalletKitClient interface {
// detected by lnd if they happen after the import. Rescans to detect past
// events will be supported later on.
ImportAccount(ctx context.Context, in *ImportAccountRequest, opts ...grpc.CallOption) (*ImportAccountResponse, error)
// ImportPublicKey imports a public key as watch-only into the wallet.
// ImportPublicKey imports a public key as watch-only into the wallet. The
// public key is converted into a simple address of the given type and that
// address script is watched on chain. For Taproot keys, this will only watch
// the BIP-0086 style output script. Use ImportTapscript for more advanced key
// spend or script spend outputs.
//
// NOTE: Events (deposits/spends) for a key will only be detected by lnd if
// they happen after the import. Rescans to detect past events will be
// supported later on.
ImportPublicKey(ctx context.Context, in *ImportPublicKeyRequest, opts ...grpc.CallOption) (*ImportPublicKeyResponse, error)
// ImportTapscript imports a Taproot script and internal key and adds the
// resulting Taproot output key as a watch-only output script into the wallet.
// For BIP-0086 style Taproot keys (no root hash commitment and no script spend
// path) use ImportPublicKey.
//
// NOTE: Events (deposits/spends) for a key will only be detected by lnd if
// they happen after the import. Rescans to detect past events will be
// supported later on.
//
// NOTE: Taproot keys imported through this RPC currently _cannot_ be used for
// funding PSBTs. Only tracking the balance and UTXOs is currently supported.
ImportTapscript(ctx context.Context, in *ImportTapscriptRequest, opts ...grpc.CallOption) (*ImportTapscriptResponse, error)
// PublishTransaction attempts to publish the passed transaction to the
// network. Once this returns without an error, the wallet will continually
// attempt to re-broadcast the transaction on start up, until it enters the
@ -305,6 +321,15 @@ func (c *walletKitClient) ImportPublicKey(ctx context.Context, in *ImportPublicK
return out, nil
}
func (c *walletKitClient) ImportTapscript(ctx context.Context, in *ImportTapscriptRequest, opts ...grpc.CallOption) (*ImportTapscriptResponse, error) {
out := new(ImportTapscriptResponse)
err := c.cc.Invoke(ctx, "/walletrpc.WalletKit/ImportTapscript", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *walletKitClient) PublishTransaction(ctx context.Context, in *Transaction, opts ...grpc.CallOption) (*PublishResponse, error) {
out := new(PublishResponse)
err := c.cc.Invoke(ctx, "/walletrpc.WalletKit/PublishTransaction", in, out, opts...)
@ -461,12 +486,28 @@ type WalletKitServer interface {
// detected by lnd if they happen after the import. Rescans to detect past
// events will be supported later on.
ImportAccount(context.Context, *ImportAccountRequest) (*ImportAccountResponse, error)
// ImportPublicKey imports a public key as watch-only into the wallet.
// ImportPublicKey imports a public key as watch-only into the wallet. The
// public key is converted into a simple address of the given type and that
// address script is watched on chain. For Taproot keys, this will only watch
// the BIP-0086 style output script. Use ImportTapscript for more advanced key
// spend or script spend outputs.
//
// NOTE: Events (deposits/spends) for a key will only be detected by lnd if
// they happen after the import. Rescans to detect past events will be
// supported later on.
ImportPublicKey(context.Context, *ImportPublicKeyRequest) (*ImportPublicKeyResponse, error)
// ImportTapscript imports a Taproot script and internal key and adds the
// resulting Taproot output key as a watch-only output script into the wallet.
// For BIP-0086 style Taproot keys (no root hash commitment and no script spend
// path) use ImportPublicKey.
//
// NOTE: Events (deposits/spends) for a key will only be detected by lnd if
// they happen after the import. Rescans to detect past events will be
// supported later on.
//
// NOTE: Taproot keys imported through this RPC currently _cannot_ be used for
// funding PSBTs. Only tracking the balance and UTXOs is currently supported.
ImportTapscript(context.Context, *ImportTapscriptRequest) (*ImportTapscriptResponse, error)
// PublishTransaction attempts to publish the passed transaction to the
// network. Once this returns without an error, the wallet will continually
// attempt to re-broadcast the transaction on start up, until it enters the
@ -610,6 +651,9 @@ func (UnimplementedWalletKitServer) ImportAccount(context.Context, *ImportAccoun
func (UnimplementedWalletKitServer) ImportPublicKey(context.Context, *ImportPublicKeyRequest) (*ImportPublicKeyResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ImportPublicKey not implemented")
}
func (UnimplementedWalletKitServer) ImportTapscript(context.Context, *ImportTapscriptRequest) (*ImportTapscriptResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method ImportTapscript not implemented")
}
func (UnimplementedWalletKitServer) PublishTransaction(context.Context, *Transaction) (*PublishResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method PublishTransaction not implemented")
}
@ -869,6 +913,24 @@ func _WalletKit_ImportPublicKey_Handler(srv interface{}, ctx context.Context, de
return interceptor(ctx, in, info, handler)
}
func _WalletKit_ImportTapscript_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(ImportTapscriptRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WalletKitServer).ImportTapscript(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/walletrpc.WalletKit/ImportTapscript",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WalletKitServer).ImportTapscript(ctx, req.(*ImportTapscriptRequest))
}
return interceptor(ctx, in, info, handler)
}
func _WalletKit_PublishTransaction_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Transaction)
if err := dec(in); err != nil {
@ -1104,6 +1166,10 @@ var WalletKit_ServiceDesc = grpc.ServiceDesc{
MethodName: "ImportPublicKey",
Handler: _WalletKit_ImportPublicKey_Handler,
},
{
MethodName: "ImportTapscript",
Handler: _WalletKit_ImportTapscript_Handler,
},
{
MethodName: "PublishTransaction",
Handler: _WalletKit_PublishTransaction_Handler,

View File

@ -154,6 +154,10 @@ var (
Entity: "onchain",
Action: "write",
}},
"/walletrpc.WalletKit/ImportTapscript": {{
Entity: "onchain",
Action: "write",
}},
}
// DefaultWalletKitMacFilename is the default name of the wallet kit
@ -1699,7 +1703,9 @@ func (w *WalletKit) ImportAccount(_ context.Context,
// address type can usually be inferred from the key's version, but in the case
// of legacy versions (xpub, tpub), an address type must be specified as we
// intend to not support importing BIP-44 keys into the wallet using the legacy
// pay-to-pubkey-hash (P2PKH) scheme.
// pay-to-pubkey-hash (P2PKH) scheme. For Taproot keys, this will only watch
// the BIP-0086 style output script. Use ImportTapscript for more advanced key
// spend or script spend outputs.
func (w *WalletKit) ImportPublicKey(_ context.Context,
req *ImportPublicKeyRequest) (*ImportPublicKeyResponse, error) {
@ -1729,3 +1735,84 @@ func (w *WalletKit) ImportPublicKey(_ context.Context,
return &ImportPublicKeyResponse{}, nil
}
// ImportTapscript imports a Taproot script and internal key and adds the
// resulting Taproot output key as a watch-only output script into the wallet.
// For BIP-0086 style Taproot keys (no root hash commitment and no script spend
// path) use ImportPublicKey.
//
// NOTE: Taproot keys imported through this RPC currently _cannot_ be used for
// funding PSBTs. Only tracking the balance and UTXOs is currently supported.
func (w *WalletKit) ImportTapscript(_ context.Context,
req *ImportTapscriptRequest) (*ImportTapscriptResponse, error) {
internalKey, err := schnorr.ParsePubKey(req.InternalPublicKey)
if err != nil {
return nil, fmt.Errorf("error parsing internal key: %v", err)
}
var tapscript *waddrmgr.Tapscript
switch {
case req.GetFullTree() != nil:
tree := req.GetFullTree()
leaves := make([]txscript.TapLeaf, len(tree.AllLeaves))
for idx, leaf := range tree.AllLeaves {
leaves[idx] = txscript.TapLeaf{
LeafVersion: txscript.TapscriptLeafVersion(
leaf.LeafVersion,
),
Script: leaf.Script,
}
}
tapscript = input.TapscriptFullTree(internalKey, leaves...)
case req.GetPartialReveal() != nil:
partialReveal := req.GetPartialReveal()
if partialReveal.RevealedLeaf == nil {
return nil, fmt.Errorf("missing revealed leaf")
}
revealedLeaf := txscript.TapLeaf{
LeafVersion: txscript.TapscriptLeafVersion(
partialReveal.RevealedLeaf.LeafVersion,
),
Script: partialReveal.RevealedLeaf.Script,
}
if len(partialReveal.FullInclusionProof)%32 != 0 {
return nil, fmt.Errorf("invalid inclusion proof "+
"length, expected multiple of 32, got %d",
len(partialReveal.FullInclusionProof)%32)
}
tapscript = input.TapscriptPartialReveal(
internalKey, revealedLeaf,
partialReveal.FullInclusionProof,
)
case req.GetRootHashOnly() != nil:
rootHash := req.GetRootHashOnly()
if len(rootHash) == 0 {
return nil, fmt.Errorf("missing root hash")
}
tapscript = input.TapscriptRootHashOnly(internalKey, rootHash)
case req.GetFullKeyOnly():
tapscript = input.TapscriptFullKeyOnly(internalKey)
default:
return nil, fmt.Errorf("invalid script")
}
taprootScope := waddrmgr.KeyScopeBIP0086
addr, err := w.cfg.Wallet.ImportTaprootScript(taprootScope, tapscript)
if err != nil {
return nil, fmt.Errorf("error importing script into wallet: %v",
err)
}
return &ImportTapscriptResponse{
P2TrAddress: addr.Address().String(),
}, nil
}