Skip to content

Commit 6cf2083

Browse files
committed
cmd: add group_key flag to tapcli assets burn
1 parent a68450d commit 6cf2083

File tree

1 file changed

+114
-24
lines changed

1 file changed

+114
-24
lines changed

cmd/commands/assets.go

Lines changed: 114 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,10 @@ var burnAssetsCommand = cli.Command{
10921092
Name: assetIDName,
10931093
Usage: "the asset ID to burn units from",
10941094
},
1095+
cli.StringFlag{
1096+
Name: assetGroupKeyName,
1097+
Usage: "the group key to burn units from",
1098+
},
10951099
cli.Uint64Flag{
10961100
Name: assetAmountName,
10971101
Usage: "the amount of units to burn/destroy",
@@ -1106,15 +1110,59 @@ var burnAssetsCommand = cli.Command{
11061110
Action: burnAssets,
11071111
}
11081112

1113+
// buildAssetSpecifier validates and constructs an AssetSpecifier from
1114+
// CLI context
1115+
func buildAssetSpecifier(ctx *cli.Context) (*taprpc.AssetSpecifier, error) {
1116+
assetIDHex := ctx.String(assetIDName)
1117+
groupKeyHex := ctx.String(assetGroupKeyName)
1118+
1119+
// Either asset ID or group key must be provided, but not both.
1120+
if assetIDHex == "" && groupKeyHex == "" {
1121+
return nil, fmt.Errorf("either asset ID or " +
1122+
"group key must be specified")
1123+
}
1124+
1125+
if assetIDHex != "" && groupKeyHex != "" {
1126+
return nil, fmt.Errorf("only one of asset ID or group key " +
1127+
"can be specified")
1128+
}
1129+
1130+
var assetSpecifier *taprpc.AssetSpecifier
1131+
if assetIDHex != "" {
1132+
assetIDBytes, err := hex.DecodeString(assetIDHex)
1133+
if err != nil {
1134+
return nil, fmt.Errorf("invalid asset ID: %w", err)
1135+
}
1136+
1137+
assetSpecifier = &taprpc.AssetSpecifier{
1138+
Id: &taprpc.AssetSpecifier_AssetId{
1139+
AssetId: assetIDBytes,
1140+
},
1141+
}
1142+
} else {
1143+
groupKeyBytes, err := hex.DecodeString(groupKeyHex)
1144+
if err != nil {
1145+
return nil, fmt.Errorf("invalid group key: %w", err)
1146+
}
1147+
1148+
assetSpecifier = &taprpc.AssetSpecifier{
1149+
Id: &taprpc.AssetSpecifier_GroupKey{
1150+
GroupKey: groupKeyBytes,
1151+
},
1152+
}
1153+
}
1154+
1155+
return assetSpecifier, nil
1156+
}
1157+
11091158
func burnAssets(ctx *cli.Context) error {
11101159
if ctx.NArg() != 0 || ctx.NumFlags() == 0 {
11111160
return cli.ShowSubcommandHelp(ctx)
11121161
}
11131162

1114-
assetIDHex := ctx.String(assetIDName)
1115-
assetIDBytes, err := hex.DecodeString(assetIDHex)
1163+
assetSpecifier, err := buildAssetSpecifier(ctx)
11161164
if err != nil {
1117-
return fmt.Errorf("invalid asset ID")
1165+
return fmt.Errorf("invalid asset specifier: %w", err)
11181166
}
11191167

11201168
burnAmount := ctx.Uint64(assetAmountName)
@@ -1127,42 +1175,84 @@ func burnAssets(ctx *cli.Context) error {
11271175
defer cleanUp()
11281176

11291177
if !ctx.Bool(burnOverrideConfirmationName) {
1130-
balance, err := client.ListBalances(
1131-
ctxc, &taprpc.ListBalancesRequest{
1132-
GroupBy: &taprpc.ListBalancesRequest_AssetId{
1133-
AssetId: true,
1134-
},
1135-
AssetFilter: assetIDBytes,
1136-
},
1178+
var (
1179+
assetSpecBytes []byte
1180+
assetSpecType string
1181+
currBalance uint64
11371182
)
1138-
if err != nil {
1139-
return fmt.Errorf("unable to list current asset "+
1140-
"balances: %w", err)
1141-
}
11421183

1143-
assetBalance, ok := balance.AssetBalances[assetIDHex]
1144-
if !ok {
1145-
return fmt.Errorf("couldn't fetch balance for asset %x",
1146-
assetIDBytes)
1184+
switch {
1185+
case assetSpecifier.GetAssetId() != nil:
1186+
assetSpecBytes = assetSpecifier.GetAssetId()
1187+
assetSpecType = "Asset ID"
1188+
idHex := hex.EncodeToString(assetSpecBytes)
1189+
1190+
// nolint: lll
1191+
balance, err := client.ListBalances(ctxc,
1192+
&taprpc.ListBalancesRequest{
1193+
GroupBy: &taprpc.ListBalancesRequest_AssetId{
1194+
AssetId: true,
1195+
},
1196+
AssetFilter: assetSpecBytes,
1197+
},
1198+
)
1199+
if err != nil {
1200+
return fmt.Errorf("unable to list current "+
1201+
"asset balances: %w", err)
1202+
}
1203+
1204+
assetBalance, ok := balance.AssetBalances[idHex]
1205+
if !ok {
1206+
return fmt.Errorf("couldn't fetch balance for "+
1207+
"asset ID %x", assetSpecBytes)
1208+
}
1209+
1210+
currBalance = assetBalance.Balance
1211+
1212+
case assetSpecifier.GetGroupKey() != nil:
1213+
assetSpecBytes = assetSpecifier.GetGroupKey()
1214+
assetSpecType = "Group Key"
1215+
gkHex := hex.EncodeToString(assetSpecBytes)
1216+
1217+
// nolint: lll
1218+
balance, err := client.ListBalances(ctxc,
1219+
&taprpc.ListBalancesRequest{
1220+
GroupBy: &taprpc.ListBalancesRequest_GroupKey{
1221+
GroupKey: true,
1222+
},
1223+
AssetFilter: assetSpecBytes,
1224+
},
1225+
)
1226+
if err != nil {
1227+
return fmt.Errorf("unable to list current "+
1228+
"asset balances: %w", err)
1229+
}
1230+
1231+
groupBalance, ok := balance.AssetGroupBalances[gkHex]
1232+
if !ok {
1233+
return fmt.Errorf("couldn't fetch balance for "+
1234+
"group key %x", assetSpecBytes)
1235+
}
1236+
1237+
currBalance = groupBalance.Balance
11471238
}
11481239

11491240
msg := fmt.Sprintf("Please confirm destructive action.\n"+
1150-
"Asset ID: %x\nCurrent available balance: %d\n"+
1241+
"%s: %x\nCurrent available balance: %d\n"+
11511242
"Amount to burn: %d\n Are you sure you want to "+
11521243
"irreversibly burn (destroy, remove from circulation) "+
11531244
"the specified amount of assets?\nPlease answer 'yes' "+
1154-
"or 'no' and press enter: ", assetIDBytes,
1155-
assetBalance.Balance, burnAmount)
1245+
"or 'no' and press enter: ",
1246+
assetSpecType, assetSpecBytes, currBalance, burnAmount,
1247+
)
11561248

11571249
if !promptForConfirmation(msg) {
11581250
return nil
11591251
}
11601252
}
11611253

11621254
resp, err := client.BurnAsset(ctxc, &taprpc.BurnAssetRequest{
1163-
Asset: &taprpc.BurnAssetRequest_AssetId{
1164-
AssetId: assetIDBytes,
1165-
},
1255+
AssetSpecifier: assetSpecifier,
11661256
AmountToBurn: burnAmount,
11671257
ConfirmationText: taprootassets.AssetBurnConfirmationText,
11681258
})

0 commit comments

Comments
 (0)