Skip to content

Commit 1f576a2

Browse files
committed
cmd: add supply commit ignore, update, and fetch commands
Add CLI commands to: - Ignore an asset outpoint in the supply commitment, - Trigger a manual on-chain update of the supply commitment, - Fetch the current supply commitment state.
1 parent bf8e101 commit 1f576a2

File tree

1 file changed

+211
-0
lines changed

1 file changed

+211
-0
lines changed

cmd/commands/universe.go

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
tap "github.com/lightninglabs/taproot-assets"
1010
"github.com/lightninglabs/taproot-assets/fn"
1111
"github.com/lightninglabs/taproot-assets/proof"
12+
"github.com/lightninglabs/taproot-assets/taprpc"
1213
unirpc "github.com/lightninglabs/taproot-assets/taprpc/universerpc"
1314
"github.com/lightninglabs/taproot-assets/universe"
1415
"github.com/lightningnetwork/lnd/lncfg"
@@ -48,6 +49,7 @@ var universeCommands = []cli.Command{
4849
universeFederationCommand,
4950
universeInfoCommand,
5051
universeStatsCommand,
52+
universeSupplyCommitCommand,
5153
},
5254
},
5355
}
@@ -1503,3 +1505,212 @@ func universeEventStatsQueryCommand(ctx *cli.Context) error {
15031505
printRespJSON(resp)
15041506
return nil
15051507
}
1508+
1509+
var universeSupplyCommitCommand = cli.Command{
1510+
Name: "supplycommit",
1511+
ShortName: "sc",
1512+
Usage: "manage the supply commitment for a Universe",
1513+
Description: `
1514+
Manage the supply commitment for a Universe. The supply commitment
1515+
is a cryptographic commitment to the total supply of assets in a
1516+
Universe.
1517+
`,
1518+
Subcommands: []cli.Command{
1519+
ignoreAssetOutPointCmd,
1520+
updateSupplyCommitCmd,
1521+
fetchSupplyCommitCmd,
1522+
},
1523+
}
1524+
1525+
var ignoreAssetOutPointCmd = cli.Command{
1526+
Name: "ignore",
1527+
Usage: "ignores an asset outpoint when committing to the asset supply",
1528+
Description: "This command allows us to ignore a specific asset UTXO " +
1529+
"when creating a new supply commitment. This is useful if " +
1530+
"an otherwise valid asset should not be counted towards the " +
1531+
"total asset group supply.",
1532+
Flags: []cli.Flag{
1533+
&cli.StringFlag{
1534+
Name: "asset_anchor_point",
1535+
Usage: "the asset anchor point to ignore, specified " +
1536+
"as txid:vout",
1537+
Required: true,
1538+
},
1539+
&cli.StringFlag{
1540+
Name: assetIDName,
1541+
Usage: "the asset ID of the asset to ignore",
1542+
Required: true,
1543+
},
1544+
&cli.StringFlag{
1545+
Name: scriptKeyName,
1546+
Usage: "the script key of the asset to ignore",
1547+
Required: true,
1548+
},
1549+
&cli.Uint64Flag{
1550+
Name: "amount",
1551+
Usage: "the amount of the asset at the anchor " +
1552+
"outpoint",
1553+
Required: true,
1554+
},
1555+
},
1556+
Action: ignoreAssetOutPoint,
1557+
}
1558+
1559+
func ignoreAssetOutPoint(ctx *cli.Context) error {
1560+
cliCtx := getContext()
1561+
client, cleanUp := getUniverseClient(ctx)
1562+
defer cleanUp()
1563+
1564+
anchorPointStr := ctx.String("asset_anchor_point")
1565+
1566+
assetID, err := hex.DecodeString(ctx.String(assetIDName))
1567+
if err != nil {
1568+
return fmt.Errorf("invalid asset_id: %w", err)
1569+
}
1570+
1571+
scriptKey, err := hex.DecodeString(ctx.String(scriptKeyName))
1572+
if err != nil {
1573+
return fmt.Errorf("invalid script_key: %w", err)
1574+
}
1575+
1576+
req := &unirpc.IgnoreAssetOutPointRequest{
1577+
AssetOutPoint: &taprpc.AssetOutPoint{
1578+
AnchorOutPoint: anchorPointStr,
1579+
AssetId: assetID,
1580+
ScriptKey: scriptKey,
1581+
},
1582+
Amount: ctx.Uint64("amount"),
1583+
}
1584+
1585+
resp, err := client.IgnoreAssetOutPoint(cliCtx, req)
1586+
if err != nil {
1587+
return err
1588+
}
1589+
1590+
printJSON(resp)
1591+
return nil
1592+
}
1593+
1594+
var updateSupplyCommitCmd = cli.Command{
1595+
Name: "update",
1596+
Usage: "updates the on-chain supply commitment for an asset group",
1597+
Description: "This command updates the on-chain supply " +
1598+
"commitment for a specific asset group.",
1599+
Flags: []cli.Flag{
1600+
&cli.StringFlag{
1601+
Name: "group_key",
1602+
Usage: "the group key of the asset group to update",
1603+
Required: true,
1604+
},
1605+
},
1606+
Action: updateSupplyCommit,
1607+
}
1608+
1609+
func updateSupplyCommit(ctx *cli.Context) error {
1610+
cliCtx := getContext()
1611+
client, cleanUp := getUniverseClient(ctx)
1612+
defer cleanUp()
1613+
1614+
req := &unirpc.UpdateSupplyCommitRequest{
1615+
GroupKey: &unirpc.UpdateSupplyCommitRequest_GroupKeyStr{
1616+
GroupKeyStr: ctx.String("group_key"),
1617+
},
1618+
}
1619+
1620+
resp, err := client.UpdateSupplyCommit(cliCtx, req)
1621+
if err != nil {
1622+
return err
1623+
}
1624+
1625+
printJSON(resp)
1626+
return nil
1627+
}
1628+
1629+
var fetchSupplyCommitCmd = cli.Command{
1630+
Name: "fetch",
1631+
Usage: "fetches the on-chain supply commitment for an asset group",
1632+
Description: "This command fetches the on-chain supply " +
1633+
"commitment for a specific asset group.",
1634+
Flags: []cli.Flag{
1635+
&cli.StringFlag{
1636+
Name: "group_key",
1637+
Usage: "the group key of the asset group to fetch",
1638+
Required: true,
1639+
},
1640+
&cli.StringSliceFlag{
1641+
Name: "issuance_leaf_keys",
1642+
Usage: "a list of issuance leaf keys to fetch " +
1643+
"inclusion proofs for",
1644+
},
1645+
&cli.StringSliceFlag{
1646+
Name: "burn_leaf_keys",
1647+
Usage: "a list of burn leaf keys to fetch inclusion " +
1648+
"proofs for",
1649+
},
1650+
&cli.StringSliceFlag{
1651+
Name: "ignore_leaf_keys",
1652+
Usage: "a list of ignore leaf keys to fetch " +
1653+
"inclusion proofs for",
1654+
},
1655+
},
1656+
Action: fetchSupplyCommit,
1657+
}
1658+
1659+
func fetchSupplyCommit(ctx *cli.Context) error {
1660+
cliCtx := getContext()
1661+
client, cleanUp := getUniverseClient(ctx)
1662+
defer cleanUp()
1663+
1664+
req := &unirpc.FetchSupplyCommitRequest{
1665+
GroupKey: &unirpc.FetchSupplyCommitRequest_GroupKeyStr{
1666+
GroupKeyStr: ctx.String("group_key"),
1667+
},
1668+
}
1669+
1670+
issuanceKeys, err := parseHexStrings(
1671+
ctx.StringSlice("issuance_leaf_keys"),
1672+
)
1673+
if err != nil {
1674+
return fmt.Errorf("invalid issuance_leaf_keys: %w", err)
1675+
}
1676+
req.IssuanceLeafKeys = issuanceKeys
1677+
1678+
burnKeys, err := parseHexStrings(ctx.StringSlice("burn_leaf_keys"))
1679+
if err != nil {
1680+
return fmt.Errorf("invalid burn_leaf_keys: %w", err)
1681+
}
1682+
req.BurnLeafKeys = burnKeys
1683+
1684+
ignoreKeys, err := parseHexStrings(ctx.StringSlice("ignore_leaf_keys"))
1685+
if err != nil {
1686+
return fmt.Errorf("invalid ignore_leaf_keys: %w", err)
1687+
}
1688+
req.IgnoreLeafKeys = ignoreKeys
1689+
1690+
resp, err := client.FetchSupplyCommit(cliCtx, req)
1691+
if err != nil {
1692+
return err
1693+
}
1694+
1695+
printJSON(resp)
1696+
return nil
1697+
}
1698+
1699+
// parseHexStrings converts a slice of hex-encoded strings into a slice of byte
1700+
// slices. Each string in hexStrings must be a valid hex representation, or an
1701+
// error is returned.
1702+
func parseHexStrings(hexStrings []string) ([][]byte, error) {
1703+
result := make([][]byte, len(hexStrings))
1704+
1705+
for i, hexStr := range hexStrings {
1706+
decoded, err := hex.DecodeString(hexStr)
1707+
if err != nil {
1708+
return nil, fmt.Errorf("invalid hex string %q: %w",
1709+
hexStr, err)
1710+
}
1711+
1712+
result[i] = decoded
1713+
}
1714+
1715+
return result, nil
1716+
}

0 commit comments

Comments
 (0)