@@ -22,6 +22,7 @@ import (
2222 "github.com/lightninglabs/taproot-assets/taprpc/mintrpc"
2323 oraclerpc "github.com/lightninglabs/taproot-assets/taprpc/priceoraclerpc"
2424 "github.com/lightninglabs/taproot-assets/taprpc/rfqrpc"
25+ "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
2526 tchrpc "github.com/lightninglabs/taproot-assets/taprpc/tapchannelrpc"
2627 "github.com/lightninglabs/taproot-assets/taprpc/universerpc"
2728 "github.com/lightninglabs/taproot-assets/tapscript"
@@ -3638,3 +3639,117 @@ func testCustomChannelsForwardBandwidth(ctxb context.Context,
36383639 universeTap , noOpCoOpCloseBalanceCheck ,
36393640 )
36403641}
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_00 , 2 ,
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 1 BTC invoice should map to 1 asset unit (1 million units as decimal display is 6).
3753+ const expectedUnits = 1_000_000
3754+ require .Equal (t .t , int64 (expectedUnits ), int64 (decodeResp .AssetAmount ))
3755+ }
0 commit comments