Skip to content

multi: hook up burn and mint events to the supply commit state machine #1675

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1344295
address: add DelegationKeyChecker interface to verify asset delegatio…
Roasbeef Jul 24, 2025
739ed86
supplycommit: add MintCommitter and BurnSupplyCommitter interfaces
Roasbeef Jul 24, 2025
cc9f927
tapgarden: extend GardenKit with delegation and supply commit support
Roasbeef Jul 24, 2025
7789f59
tapfreighter: add delegation key filtering for burn supply commits
Roasbeef Jul 24, 2025
792205c
tapgarden: add delegation key filtering for mint supply commits
Roasbeef Jul 24, 2025
6268d6b
tapcfg: wire delegation checker to garden and freighter subsystems
Roasbeef Jul 24, 2025
02bd668
tapgarden: add tests for mint supply commit delegation key filtering
Roasbeef Jul 24, 2025
722a4e9
tapfreighter: add tests for burn supply commit filtering
Roasbeef Jul 24, 2025
28d16b2
universe: add new CommitPoint() and TapscriptRoot() methods to RootCo…
Roasbeef Aug 15, 2025
76ec20b
multi: add outpoint field to mint anchor uni commitment
Roasbeef Aug 15, 2025
8666427
tapdb: set the outpoint of a pre commitment during insertion
Roasbeef Aug 15, 2025
6157831
tapdb: remove extra call to applySupplyUpdatesInternal
Roasbeef Aug 15, 2025
8af377b
tapdb: make sure we actually mark pre commitments as spent
Roasbeef Aug 15, 2025
92c96c2
tapdb: add test to ensure pre commitment spend detection works
Roasbeef Aug 15, 2025
4120388
tapdb: fix bug by ensuring that we write the full keydesc to disk
Roasbeef Aug 15, 2025
a9cedbb
universe/supplycommit: fix PSBT bug, ensure the TaprootMerkleRoot is set
Roasbeef Aug 15, 2025
15f7297
universe/supplycommit: add additional logging
Roasbeef Aug 15, 2025
81c687c
itest: add supply commit mint/burn itests
Roasbeef Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions address/book.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,12 @@ type Storage interface {
// database.
FetchAllAssetMeta(
ctx context.Context) (map[asset.ID]*proof.MetaReveal, error)

// FetchInternalKeyLocator attempts to fetch the key locator information
// for the given raw internal key. If the key cannot be found, then
// ErrInternalKeyNotFound is returned.
FetchInternalKeyLocator(ctx context.Context,
rawKey *btcec.PublicKey) (keychain.KeyLocator, error)
}

// KeyRing is used to create script and internal keys for Taproot Asset
Expand Down Expand Up @@ -841,3 +847,73 @@ func (b *Book) RemoveSubscriber(

return nil
}

// DelegationKeyChecker is used to verify that we control the delegation key
// for a given asset, which is required for creating supply commitments.
type DelegationKeyChecker interface {
// HasDelegationKey checks if we control the delegation key for the
// given asset ID. Returns true if we have the private key for the
// asset's delegation key, false otherwise.
HasDelegationKey(ctx context.Context, assetID asset.ID) (bool, error)
}

// HasDelegationKey checks if we control the delegation key for the given
// asset ID. Returns true if we have the private key for the asset's
// delegation key, false otherwise.
//
// NOTE: This is part of the DelegationKeyChecker interface.
func (b *Book) HasDelegationKey(ctx context.Context,
assetID asset.ID) (bool, error) {

assetGroup, err := b.cfg.Store.QueryAssetGroupByID(ctx, assetID)
if err != nil {
return false, fmt.Errorf("fail to find asset group given "+
"asset ID: %w", err)
}

// If the asset doesn't have a group, it can't have a delegation key. So
// we just return false here.
if assetGroup == nil || assetGroup.GroupKey == nil {
return false, nil
}

// Retrieve asset meta reveal for the asset ID. This will be used to
// obtain the supply commitment delegation key.
metaReveal, err := b.cfg.Store.FetchAssetMetaForAsset(ctx, assetID)
if err != nil {
return false, fmt.Errorf("failed to fetch asset meta: %w", err)
}

// If there's no meta reveal or delegation key, we can't control it.
if metaReveal == nil || metaReveal.DelegationKey.IsNone() {
return false, nil
}

delegationPubKey, err := metaReveal.DelegationKey.UnwrapOrErr(
fmt.Errorf("delegation key not found for given asset"),
)
if err != nil {
return false, err
}

// Now that we have the delegation key, we'll see if we know of the
// internal key loactor. If we do, then this means that we were the ones
// that created it in the first place.
_, err = b.cfg.Store.FetchInternalKeyLocator(ctx, &delegationPubKey)
switch {
// If we get this error, then we don't control this delegation key.
case errors.Is(err, ErrInternalKeyNotFound):
return false, nil
case err != nil:
return false, fmt.Errorf("failed to fetch delegation key "+
"locator: %w", err)
}

// If we reached this point, then we know that we control the delegation
// key.
return true, nil
}

// A compile-time assertion to ensure Book implements the DelegationKeyChecker
// interface.
var _ DelegationKeyChecker = (*Book)(nil)
Loading
Loading