4
4
"bytes"
5
5
"context"
6
6
"crypto/sha256"
7
+ "errors"
7
8
"fmt"
8
9
"net/url"
9
10
@@ -15,6 +16,7 @@ import (
15
16
"github.com/btcsuite/btcd/txscript"
16
17
"github.com/btcsuite/btcd/wire"
17
18
"github.com/btcsuite/btclog/v2"
19
+ "github.com/lightninglabs/taproot-assets/address"
18
20
"github.com/lightninglabs/taproot-assets/asset"
19
21
"github.com/lightninglabs/taproot-assets/fn"
20
22
"github.com/lightninglabs/taproot-assets/mssmt"
@@ -237,9 +239,9 @@ type AssetLookup interface {
237
239
rawKey * btcec.PublicKey ) (keychain.KeyLocator , error )
238
240
}
239
241
240
- // fetchLatestAssetMetadata returns the latest asset metadata for the
242
+ // FetchLatestAssetMetadata returns the latest asset metadata for the
241
243
// given asset specifier.
242
- func fetchLatestAssetMetadata (ctx context.Context , lookup AssetLookup ,
244
+ func FetchLatestAssetMetadata (ctx context.Context , lookup AssetLookup ,
243
245
assetSpec asset.Specifier ) (proof.MetaReveal , error ) {
244
246
245
247
var zero proof.MetaReveal
@@ -271,6 +273,68 @@ func fetchLatestAssetMetadata(ctx context.Context, lookup AssetLookup,
271
273
return * metaReveal , nil
272
274
}
273
275
276
+ // CheckSupplyCommitSupport verifies that the asset group for the given
277
+ // asset specifier supports supply commitments, and that this node can generate
278
+ // supply commitments for it.
279
+ func CheckSupplyCommitSupport (ctx context.Context , assetLookup AssetLookup ,
280
+ assetSpec asset.Specifier , locallyControlled bool ) error {
281
+
282
+ // Fetch the latest asset metadata for the asset group.
283
+ metaReveal , err := FetchLatestAssetMetadata (
284
+ ctx , assetLookup , assetSpec ,
285
+ )
286
+ if err != nil {
287
+ return fmt .Errorf ("faild to fetch asset meta: %w" , err )
288
+ }
289
+
290
+ // If the universe commitment flag is not set on the asset metadata,
291
+ // then the asset group does not support supply commitments.
292
+ if ! metaReveal .UniverseCommitments {
293
+ return fmt .Errorf ("asset group metadata universe " +
294
+ "commitments flag indicates that asset does not " +
295
+ "support supply commitments" )
296
+ }
297
+
298
+ // If a delegation key is not present, then the asset group does not
299
+ // support supply commitments.
300
+ if metaReveal .DelegationKey .IsNone () {
301
+ return fmt .Errorf ("asset group metadata does not " +
302
+ "specify delegation key, which is required for " +
303
+ "supply commitments" )
304
+ }
305
+
306
+ // Extract supply commitment delegation pub key from the asset metadata.
307
+ delegationPubKey , err := metaReveal .DelegationKey .UnwrapOrErr (
308
+ fmt .Errorf ("delegation key not found for given asset" ),
309
+ )
310
+ if err != nil {
311
+ return err
312
+ }
313
+
314
+ // Fetch the delegation key locator. We need to ensure that the
315
+ // delegation key is owned by this node, so that we can generate
316
+ // supply commitments (ignore tuples) for this asset group.
317
+ _ , err = assetLookup .FetchInternalKeyLocator (
318
+ ctx , & delegationPubKey ,
319
+ )
320
+ switch {
321
+ case errors .Is (err , address .ErrInternalKeyNotFound ):
322
+ // If local key control is expected, then we return an error
323
+ // if the delegation key locator is not found.
324
+ if locallyControlled {
325
+ return fmt .Errorf ("delegation key locator not found; " +
326
+ "only delegation key owners can generate " +
327
+ "supply commitments" )
328
+ }
329
+
330
+ case err != nil :
331
+ return fmt .Errorf ("failed to fetch delegation key locator: %w" ,
332
+ err )
333
+ }
334
+
335
+ return nil
336
+ }
337
+
274
338
// SupplyTreeView is an interface that allows the state machine to obtain an up
275
339
// to date snapshot of the root supply tree, as the sub trees (ignore, burn,
276
340
// mint) committed in the main supply tree.
0 commit comments