Skip to content

Commit 5797027

Browse files
committed
tapas_loopout
1 parent 10c15c0 commit 5797027

35 files changed

+6367
-10
lines changed

assets/actions.go

+421
Large diffs are not rendered by default.

assets/client.go

+244
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,31 @@ import (
88
"sync"
99
"time"
1010

11+
"bytes"
12+
1113
"github.com/btcsuite/btcd/btcutil"
14+
"github.com/btcsuite/btcd/btcutil/psbt"
15+
"github.com/lightninglabs/taproot-assets/asset"
1216
"github.com/lightninglabs/taproot-assets/tapcfg"
17+
"github.com/lightninglabs/taproot-assets/tappsbt"
1318
"github.com/lightninglabs/taproot-assets/taprpc"
19+
wrpc "github.com/lightninglabs/taproot-assets/taprpc/assetwalletrpc"
20+
"github.com/lightninglabs/taproot-assets/taprpc/mintrpc"
1421
"github.com/lightninglabs/taproot-assets/taprpc/priceoraclerpc"
1522
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
1623
"github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
24+
"github.com/lightninglabs/taproot-assets/taprpc/tapdevrpc"
1725
"github.com/lightninglabs/taproot-assets/taprpc/universerpc"
26+
"github.com/lightninglabs/taproot-assets/tapsend"
27+
"github.com/lightningnetwork/lnd/keychain"
1828
"github.com/lightningnetwork/lnd/lnrpc"
29+
"github.com/lightningnetwork/lnd/lnwallet/chainfee"
1930
"github.com/lightningnetwork/lnd/lnwire"
2031
"github.com/lightningnetwork/lnd/macaroons"
2132
"google.golang.org/grpc"
33+
"google.golang.org/grpc/codes"
2234
"google.golang.org/grpc/credentials"
35+
"google.golang.org/grpc/status"
2336
"gopkg.in/macaroon.v2"
2437
)
2538

@@ -63,7 +76,10 @@ type TapdClient struct {
6376
tapchannelrpc.TaprootAssetChannelsClient
6477
priceoraclerpc.PriceOracleClient
6578
rfqrpc.RfqClient
79+
wrpc.AssetWalletClient
80+
mintrpc.MintClient
6681
universerpc.UniverseClient
82+
tapdevrpc.TapDevClient
6783

6884
cfg *TapdConfig
6985
assetNameCache map[string]string
@@ -242,3 +258,231 @@ func getClientConn(config *TapdConfig) (*grpc.ClientConn, error) {
242258

243259
return conn, nil
244260
}
261+
262+
// FundAndSignVpacket funds ands signs a vpacket.
263+
func (t *TapdClient) FundAndSignVpacket(ctx context.Context,
264+
vpkt *tappsbt.VPacket) (*tappsbt.VPacket, error) {
265+
266+
// Fund the packet.
267+
var buf bytes.Buffer
268+
err := vpkt.Serialize(&buf)
269+
if err != nil {
270+
return nil, err
271+
}
272+
273+
fundResp, err := t.FundVirtualPsbt(
274+
ctx, &wrpc.FundVirtualPsbtRequest{
275+
Template: &wrpc.FundVirtualPsbtRequest_Psbt{
276+
Psbt: buf.Bytes(),
277+
},
278+
},
279+
)
280+
if err != nil {
281+
return nil, err
282+
}
283+
284+
// Sign the packet.
285+
signResp, err := t.SignVirtualPsbt(
286+
ctx, &wrpc.SignVirtualPsbtRequest{
287+
FundedPsbt: fundResp.FundedPsbt,
288+
},
289+
)
290+
if err != nil {
291+
return nil, err
292+
}
293+
294+
return tappsbt.NewFromRawBytes(
295+
bytes.NewReader(signResp.SignedPsbt), false,
296+
)
297+
}
298+
299+
// PrepareAndCommitVirtualPsbts prepares and commits virtual psbts.
300+
func (t *TapdClient) PrepareAndCommitVirtualPsbts(ctx context.Context,
301+
vpkt *tappsbt.VPacket, feeRateSatPerKVByte chainfee.SatPerVByte) (
302+
*psbt.Packet, []*tappsbt.VPacket, []*tappsbt.VPacket,
303+
*wrpc.CommitVirtualPsbtsResponse, error) {
304+
305+
htlcVPackets, err := tappsbt.Encode(vpkt)
306+
if err != nil {
307+
return nil, nil, nil, nil, err
308+
}
309+
310+
htlcBtcPkt, err := tapsend.PrepareAnchoringTemplate(
311+
[]*tappsbt.VPacket{vpkt},
312+
)
313+
if err != nil {
314+
return nil, nil, nil, nil, err
315+
}
316+
317+
var buf bytes.Buffer
318+
err = htlcBtcPkt.Serialize(&buf)
319+
if err != nil {
320+
return nil, nil, nil, nil, err
321+
}
322+
323+
commitResponse, err := t.AssetWalletClient.CommitVirtualPsbts(
324+
ctx, &wrpc.CommitVirtualPsbtsRequest{
325+
AnchorPsbt: buf.Bytes(),
326+
Fees: &wrpc.CommitVirtualPsbtsRequest_SatPerVbyte{
327+
SatPerVbyte: uint64(feeRateSatPerKVByte),
328+
},
329+
AnchorChangeOutput: &wrpc.CommitVirtualPsbtsRequest_Add{
330+
Add: true,
331+
},
332+
VirtualPsbts: [][]byte{
333+
htlcVPackets,
334+
},
335+
},
336+
)
337+
if err != nil {
338+
return nil, nil, nil, nil, err
339+
}
340+
341+
fundedPacket, err := psbt.NewFromRawBytes(
342+
bytes.NewReader(commitResponse.AnchorPsbt), false,
343+
)
344+
if err != nil {
345+
return nil, nil, nil, nil, err
346+
}
347+
348+
activePackets := make(
349+
[]*tappsbt.VPacket, len(commitResponse.VirtualPsbts),
350+
)
351+
for idx := range commitResponse.VirtualPsbts {
352+
activePackets[idx], err = tappsbt.Decode(
353+
commitResponse.VirtualPsbts[idx],
354+
)
355+
if err != nil {
356+
return nil, nil, nil, nil, err
357+
}
358+
}
359+
360+
passivePackets := make(
361+
[]*tappsbt.VPacket, len(commitResponse.PassiveAssetPsbts),
362+
)
363+
for idx := range commitResponse.PassiveAssetPsbts {
364+
passivePackets[idx], err = tappsbt.Decode(
365+
commitResponse.PassiveAssetPsbts[idx],
366+
)
367+
if err != nil {
368+
return nil, nil, nil, nil, err
369+
}
370+
}
371+
372+
return fundedPacket, activePackets, passivePackets, commitResponse, nil
373+
}
374+
375+
// LogAndPublish logs and publishes the virtual psbts.
376+
func (t *TapdClient) LogAndPublish(ctx context.Context, btcPkt *psbt.Packet,
377+
activeAssets []*tappsbt.VPacket, passiveAssets []*tappsbt.VPacket,
378+
commitResp *wrpc.CommitVirtualPsbtsResponse) (*taprpc.SendAssetResponse,
379+
error) {
380+
381+
var buf bytes.Buffer
382+
err := btcPkt.Serialize(&buf)
383+
if err != nil {
384+
return nil, err
385+
}
386+
387+
request := &wrpc.PublishAndLogRequest{
388+
AnchorPsbt: buf.Bytes(),
389+
VirtualPsbts: make([][]byte, len(activeAssets)),
390+
PassiveAssetPsbts: make([][]byte, len(passiveAssets)),
391+
ChangeOutputIndex: commitResp.ChangeOutputIndex,
392+
LndLockedUtxos: commitResp.LndLockedUtxos,
393+
}
394+
395+
for idx := range activeAssets {
396+
request.VirtualPsbts[idx], err = tappsbt.Encode(
397+
activeAssets[idx],
398+
)
399+
if err != nil {
400+
return nil, err
401+
}
402+
}
403+
for idx := range passiveAssets {
404+
request.PassiveAssetPsbts[idx], err = tappsbt.Encode(
405+
passiveAssets[idx],
406+
)
407+
if err != nil {
408+
return nil, err
409+
}
410+
}
411+
412+
resp, err := t.PublishAndLogTransfer(ctx, request)
413+
if err != nil {
414+
return nil, err
415+
}
416+
417+
return resp, nil
418+
}
419+
420+
// CheckBalanceById checks the balance of an asset by its id.
421+
func (t *TapdClient) CheckBalanceById(ctx context.Context, assetId []byte,
422+
requestedBalance btcutil.Amount) error {
423+
424+
// Check if we have enough funds to do the swap.
425+
balanceResp, err := t.ListBalances(
426+
ctx, &taprpc.ListBalancesRequest{
427+
GroupBy: &taprpc.ListBalancesRequest_AssetId{
428+
AssetId: true,
429+
},
430+
AssetFilter: assetId,
431+
},
432+
)
433+
if err != nil {
434+
return err
435+
}
436+
437+
// Check if we have enough funds to do the swap.
438+
balance, ok := balanceResp.AssetBalances[hex.EncodeToString(
439+
assetId,
440+
)]
441+
if !ok {
442+
return status.Error(
443+
codes.Internal, "internal error",
444+
)
445+
}
446+
if balance.Balance < uint64(requestedBalance) {
447+
return status.Error(
448+
codes.Internal, "internal error",
449+
)
450+
}
451+
452+
return nil
453+
}
454+
455+
// DeriveNewKeys derives a new internal and script key.
456+
func (t *TapdClient) DeriveNewKeys(ctx context.Context) (asset.ScriptKey,
457+
keychain.KeyDescriptor, error) {
458+
scriptKeyDesc, err := t.NextScriptKey(
459+
ctx, &wrpc.NextScriptKeyRequest{
460+
KeyFamily: uint32(asset.TaprootAssetsKeyFamily),
461+
},
462+
)
463+
if err != nil {
464+
return asset.ScriptKey{}, keychain.KeyDescriptor{}, err
465+
}
466+
467+
scriptKey, err := taprpc.UnmarshalScriptKey(scriptKeyDesc.ScriptKey)
468+
if err != nil {
469+
return asset.ScriptKey{}, keychain.KeyDescriptor{}, err
470+
}
471+
472+
internalKeyDesc, err := t.NextInternalKey(
473+
ctx, &wrpc.NextInternalKeyRequest{
474+
KeyFamily: uint32(asset.TaprootAssetsKeyFamily),
475+
},
476+
)
477+
if err != nil {
478+
return asset.ScriptKey{}, keychain.KeyDescriptor{}, err
479+
}
480+
internalKeyLnd, err := taprpc.UnmarshalKeyDescriptor(
481+
internalKeyDesc.InternalKey,
482+
)
483+
if err != nil {
484+
return asset.ScriptKey{}, keychain.KeyDescriptor{}, err
485+
}
486+
487+
return *scriptKey, internalKeyLnd, nil
488+
}

0 commit comments

Comments
 (0)