@@ -22,6 +22,7 @@ import (
22
22
"github.com/lightninglabs/taproot-assets/taprpc/mintrpc"
23
23
oraclerpc "github.com/lightninglabs/taproot-assets/taprpc/priceoraclerpc"
24
24
"github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
25
+ "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
25
26
tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
26
27
"github.com/lightninglabs/taproot-assets/taprpc/universerpc"
27
28
"github.com/lightninglabs/taproot-assets/tapscript"
@@ -3638,3 +3639,125 @@ func testCustomChannelsForwardBandwidth(ctxb context.Context,
3638
3639
universeTap , noOpCoOpCloseBalanceCheck ,
3639
3640
)
3640
3641
}
3642
+
3643
+ // testCustomChannelsDecodeAssetInvoice tests that we're able to properly
3644
+ // decode and display asset invoice related information.
3645
+ //
3646
+ // TODO(roasbeef): just move to tapd repo due to new version that doesn't req a
3647
+ // chan?
3648
+ func testCustomChannelsDecodeAssetInvoice (ctx context.Context ,
3649
+ net * NetworkHarness , t * harnessTest ) {
3650
+
3651
+ // First, we'll set up some information for our custom oracle that we'll use
3652
+ // to feed in price information.
3653
+ oracleAddr := fmt .Sprintf ("localhost:%d" , port .NextAvailablePort ())
3654
+ oracle := newOracleHarness (oracleAddr )
3655
+ oracle .start (t .t )
3656
+ t .t .Cleanup (oracle .stop )
3657
+
3658
+ ctxb := context .Background ()
3659
+ lndArgs := slices .Clone (lndArgsTemplate )
3660
+ litdArgs := slices .Clone (litdArgsTemplateNoOracle )
3661
+ litdArgs = append (litdArgs , fmt .Sprintf (
3662
+ "--taproot-assets.experimental.rfq.priceoracleaddress=" +
3663
+ "rfqrpc://%s" , oracleAddr ,
3664
+ ))
3665
+
3666
+ // For this test, Zane will be our dedicated Universe server for all parties.
3667
+ zane , err := net .NewNode (
3668
+ t .t , "Zane" , lndArgs , false , true , litdArgs ... ,
3669
+ )
3670
+ require .NoError (t .t , err )
3671
+
3672
+ litdArgs = append (litdArgs , fmt .Sprintf (
3673
+ "--taproot-assets.proofcourieraddr=%s://%s" ,
3674
+ proof .UniverseRpcCourierType , zane .Cfg .LitAddr (),
3675
+ ))
3676
+
3677
+ // We'll just make a single node here, as this doesn't actually rely on a set
3678
+ // of active channels.
3679
+ alice , err := net .NewNode (t .t , "Alice" , lndArgs , false , true , litdArgs ... )
3680
+ aliceTap := newTapClient (t .t , alice )
3681
+
3682
+ // Fund Alice so she'll have enough funds to mint the asset.
3683
+ fundAllNodes (t .t , net , []* HarnessNode {alice })
3684
+
3685
+ // Next, we'll make a new asset with a specified decimal display. We'll also
3686
+ // make grouped asset as well.
3687
+ usdMetaData := & taprpc.AssetMeta {
3688
+ Data : []byte (`{
3689
+ "description":"this is a USD stablecoin with decimal display of 6"
3690
+ }` ),
3691
+ Type : taprpc .AssetMetaType_META_TYPE_JSON ,
3692
+ }
3693
+
3694
+ const decimalDisplay = 6
3695
+ itestAsset = & mintrpc.MintAsset {
3696
+ AssetType : taprpc .AssetType_NORMAL ,
3697
+ Name : "USD" ,
3698
+ AssetMeta : usdMetaData ,
3699
+ // We mint 1 million USD with a decimal display of 6, which
3700
+ // results in 1 trillion asset units.
3701
+ Amount : 1_000_000_000_000 ,
3702
+ DecimalDisplay : decimalDisplay ,
3703
+ NewGroupedAsset : true ,
3704
+ }
3705
+
3706
+ // Mint an asset on Charlie and sync Dave to Charlie as the universe.
3707
+ mintedAssets := itest .MintAssetsConfirmBatch (
3708
+ t .t , t .lndHarness .Miner .Client , aliceTap ,
3709
+ []* mintrpc.MintAssetRequest {
3710
+ {
3711
+ Asset : itestAsset ,
3712
+ },
3713
+ },
3714
+ )
3715
+ usdAsset := mintedAssets [0 ]
3716
+ assetID := usdAsset .AssetGenesis .AssetId
3717
+
3718
+ // Now that we've minted the asset, we can set the price in the oracle.
3719
+ var id asset.ID
3720
+ copy (id [:], assetID )
3721
+
3722
+ // We'll assume a price of $100,000.00 USD for a single BTC. This is just the
3723
+ // current subjective price our oracle will use. From this BTC price, we'll
3724
+ // scale things up to be in the precision of the asset we minted above.
3725
+ btcPrice := rfqmath .NewBigIntFixedPoint (
3726
+ 100_000 , 0 ,
3727
+ ).ScaleTo (decimalDisplay )
3728
+ oracle .setPrice (id , btcPrice , btcPrice )
3729
+
3730
+ // Now we'll make a normal invoice for 1 BTC using Alice.
3731
+ expirySeconds := 10
3732
+ amountSat := 100_000_000
3733
+ invoiceResp , err := alice .AddInvoice (ctxb , & lnrpc.Invoice {
3734
+ Value : int64 (amountSat ),
3735
+ Memo : "normal invoice" ,
3736
+ Expiry : int64 (expirySeconds ),
3737
+ })
3738
+ require .NoError (t .t , err )
3739
+
3740
+ payReq := invoiceResp .PaymentRequest
3741
+
3742
+ // Now that we have our payment request, we'll call into the new decode asset
3743
+ // pay req call.
3744
+ decodeResp , err := aliceTap .DecodeAssetPayReq (ctxb , & tapchannelrpc.AssetPayReqString {
3745
+ AssetId : assetID ,
3746
+ PayReqString : & lnrpc.PayReqString {
3747
+ PayReq : payReq ,
3748
+ },
3749
+ })
3750
+ require .NoError (t .t , err )
3751
+
3752
+ // The decimal display information, genesis, and asset group information
3753
+ // should all match.
3754
+ require .Equal (
3755
+ t .t , int64 (decimalDisplay ), int64 (decodeResp .DecimalDisplay .DecimalDisplay ),
3756
+ )
3757
+ require .Equal (t .t , usdAsset .AssetGenesis , decodeResp .GenesisInfo )
3758
+ require .Equal (t .t , usdAsset .AssetGroup , decodeResp .AssetGroup )
3759
+
3760
+ // The 1 BTC invoice should map to 1 asset unit (1 million units as decimal display is 6).
3761
+ const expectedUnits = 1_000_000
3762
+ require .Equal (t .t , int64 (expectedUnits ), int64 (decodeResp .AssetAmount ))
3763
+ }
0 commit comments