|
9 | 9 | tap "github.com/lightninglabs/taproot-assets"
|
10 | 10 | "github.com/lightninglabs/taproot-assets/fn"
|
11 | 11 | "github.com/lightninglabs/taproot-assets/proof"
|
| 12 | + "github.com/lightninglabs/taproot-assets/taprpc" |
12 | 13 | unirpc "github.com/lightninglabs/taproot-assets/taprpc/universerpc"
|
13 | 14 | "github.com/lightninglabs/taproot-assets/universe"
|
14 | 15 | "github.com/lightningnetwork/lnd/lncfg"
|
@@ -48,6 +49,7 @@ var universeCommands = []cli.Command{
|
48 | 49 | universeFederationCommand,
|
49 | 50 | universeInfoCommand,
|
50 | 51 | universeStatsCommand,
|
| 52 | + universeSupplyCommitCommand, |
51 | 53 | },
|
52 | 54 | },
|
53 | 55 | }
|
@@ -1503,3 +1505,212 @@ func universeEventStatsQueryCommand(ctx *cli.Context) error {
|
1503 | 1505 | printRespJSON(resp)
|
1504 | 1506 | return nil
|
1505 | 1507 | }
|
| 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