11package assets
22
33import (
4+ "context"
5+ "fmt"
6+ "math/big"
47 "os"
8+ "time"
59
10+ "github.com/btcsuite/btcd/btcutil"
11+ "github.com/lightninglabs/taproot-assets/rfqmath"
612 "github.com/lightninglabs/taproot-assets/taprpc"
13+ "github.com/lightninglabs/taproot-assets/taprpc/priceoraclerpc"
14+ "github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
715 "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
816 "github.com/lightningnetwork/lnd/macaroons"
917 "google.golang.org/grpc"
@@ -33,6 +41,15 @@ func DefaultTapdConfig() *TapdConfig {
3341 }
3442}
3543
44+ // TapdClient is a client for the Tap daemon.
45+ type TapdClient struct {
46+ cc * grpc.ClientConn
47+ taprpc.TaprootAssetsClient
48+ tapchannelrpc.TaprootAssetChannelsClient
49+ priceoraclerpc.PriceOracleClient
50+ rfqrpc.RfqClient
51+ }
52+
3653// NewTapdClient retusn a new taproot assets client.
3754func NewTapdClient (config * TapdConfig ) (* TapdClient , error ) {
3855 // Create the client connection to the server.
@@ -46,6 +63,8 @@ func NewTapdClient(config *TapdConfig) (*TapdClient, error) {
4663 cc : conn ,
4764 TaprootAssetsClient : taprpc .NewTaprootAssetsClient (conn ),
4865 TaprootAssetChannelsClient : tapchannelrpc .NewTaprootAssetChannelsClient (conn ),
66+ PriceOracleClient : priceoraclerpc .NewPriceOracleClient (conn ),
67+ RfqClient : rfqrpc .NewRfqClient (conn ),
4968 }
5069
5170 return client , nil
@@ -56,11 +75,57 @@ func (c *TapdClient) Close() {
5675 c .cc .Close ()
5776}
5877
59- // TapdClient is a client for the Tap daemon.
60- type TapdClient struct {
61- cc * grpc.ClientConn
62- taprpc.TaprootAssetsClient
63- tapchannelrpc.TaprootAssetChannelsClient
78+ func (c * TapdClient ) GetSatAmountForAsset (ctx context.Context ,
79+ amt btcutil.Amount , assetId , peerPubkey []byte ) (btcutil.Amount ,
80+ error ) {
81+
82+ rfq , err := c .RfqClient .AddAssetSellOrder (
83+ ctx , & rfqrpc.AddAssetSellOrderRequest {
84+ AssetSpecifier : & rfqrpc.AssetSpecifier {
85+ Id : & rfqrpc.AssetSpecifier_AssetId { // nolint:lll
86+ AssetId : assetId ,
87+ },
88+ },
89+ PeerPubKey : peerPubkey ,
90+ PaymentMaxAmt : uint64 (amt ),
91+ Expiry : uint64 (time .Now ().Add (1 * time .Hour ).Unix ()),
92+ TimeoutSeconds : 60 ,
93+ })
94+ if err != nil {
95+ return 0 , err
96+ }
97+ if rfq .GetInvalidQuote () != nil {
98+ return 0 , fmt .Errorf ("invalid RFQ: %v" , rfq .GetInvalidQuote ())
99+ }
100+ if rfq .GetRejectedQuote () != nil {
101+ return 0 , fmt .Errorf ("rejected RFQ: %v" , rfq .GetRejectedQuote ())
102+ }
103+
104+ if rfq .GetAcceptedQuote () != nil {
105+ payRate := rfq .GetAcceptedQuote ().BidAssetRate
106+
107+ coefficient := new (big.Int )
108+ coefficient , ok := coefficient .SetString (payRate .Coefficient , 10 )
109+ if ! ok {
110+ return 0 , fmt .Errorf ("failed to parse coefficient %v" ,
111+ payRate .Coefficient )
112+ }
113+
114+ amt := rfqmath .FixedPointFromUint64 [rfqmath.BigInt ](
115+ uint64 (amt ), 0 ,
116+ )
117+
118+ price := rfqmath.FixedPoint [rfqmath.BigInt ]{
119+ Coefficient : rfqmath .NewBigInt (coefficient ),
120+ Scale : uint8 (payRate .Scale ),
121+ }
122+
123+ msats := rfqmath .UnitsToMilliSatoshi (amt , price )
124+
125+ return msats .ToSatoshis (), nil
126+ }
127+
128+ return 0 , fmt .Errorf ("no accepted quote" )
64129}
65130
66131func getClientConn (config * TapdConfig ) (* grpc.ClientConn , error ) {
0 commit comments