asset

package
v0.5.1-rc2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 28, 2025 License: MIT Imports: 39 Imported by: 1

Documentation

Index

Constants

View Source
const (
	// MaxAssetNameLength is the maximum byte length of an asset's name.
	// This byte length is equivalent to character count for single-byte
	// UTF-8 characters.
	MaxAssetNameLength = 64

	// MaxAssetEncodeSizeBytes is the size we expect an asset to not exceed
	// in its encoded form. This is used to prevent OOMs when decoding
	// assets. The main contributing factor to this size are the previous
	// witnesses which we currently allow to number up to 65k witnesses.
	MaxAssetEncodeSizeBytes = blockchain.MaxBlockWeight

	// PedersenXPubMasterKeyFingerprint is the master key fingerprint we use
	// to identify the fake xPub we create from a Pedersen commitment public
	// key (which is a special form of tweaked NUMS key). Master key
	// fingerprints in PSBTs are always encoded as little-endian uint32s but
	// displayed as 4 bytes of hex. Serialized as little-endian uint32, this
	// spells "7a9a55e7" which can be read as "TAP asset" in leet speak
	// (with a bit of imagination).
	PedersenXPubMasterKeyFingerprint uint32 = 0xe7559a7a
)
View Source
const (
	// MaxPrevWitnesses is the maximum number of PrevWitness objects
	// that will be generated when generating []Witness.
	MaxPrevWitnesses = 8

	// MaxTxWitnessElementCount is the maximum number of elements in a
	MaxTxWitnessElementCount = 64

	// MaxTxWitnessElementSize is the maximum size of a single object in a
	// generated witness stack.
	MaxTxWitnessElementSize = 64
)
View Source
const (
	// MetaHashLen is the length of the metadata hash.
	MetaHashLen = 32
)
View Source
const TapBranchNodesLen = 64

TapBranchNodesLen is the length of a TapBranch represented as a byte arrray.

View Source
const (
	// TaprootAssetsKeyFamily is the key family used to generate internal
	// keys that tapd will use creating internal taproot keys and also any
	// other keys used for asset script keys.
	// This was derived via: sum(map(lambda y: ord(y), 'tapd')).
	// In order words: take the word tapd and return the integer
	// representation of each character and sum those. We get 425, then
	// divide that by 2, to allow us to fit this into just a 2-byte integer
	// and to ensure compatibility with the remote signer.
	TaprootAssetsKeyFamily = 212
)

Variables

View Source
var (
	// ZeroPrevID is the blank prev ID used for genesis assets and also
	// asset split leaves.
	ZeroPrevID PrevID

	// EmptyGenesis is the empty Genesis struct used for alt leaves.
	EmptyGenesis Genesis

	// EmptyGenesisID is the ID of the empty genesis struct.
	EmptyGenesisID = EmptyGenesis.ID()

	// NUMSBytes is the NUMS point we'll use for un-spendable script keys.
	// It was generated via a try-and-increment approach using the phrase
	// "taproot-assets" with SHA2-256. The code for the try-and-increment
	// approach can be seen here:
	// https://github.com/lightninglabs/lightning-node-connect/tree/master/mailbox/numsgen
	NUMSBytes, _ = hex.DecodeString(
		"027c79b9b26e463895eef5679d8558942c86c4ad2233adef01bc3e6d540b" +
			"3653fe",
	)
	NUMSPubKey, _     = btcec.ParsePubKey(NUMSBytes)
	NUMSCompressedKey = ToSerialized(NUMSPubKey)
	NUMSScriptKey     = ScriptKey{
		PubKey: NUMSPubKey,
	}

	// ErrUnknownVersion is returned when an asset with an unknown asset
	// version is being used.
	ErrUnknownVersion = errors.New("asset: unknown asset version")

	// ErrUnwrapAssetID is returned when an asset ID cannot be unwrapped
	// from a Specifier.
	ErrUnwrapAssetID = errors.New("unable to unwrap asset ID")

	// ErrDuplicateAltLeafKey is returned when a slice of AltLeaves contains
	// 2 or more AltLeaves with the same AssetCommitmentKey.
	ErrDuplicateAltLeafKey = errors.New("duplicate alt leaf key")
)
View Source
var (
	// ErrTooManyInputs is returned when an asset TLV atempts to reference
	// too many inputs.
	ErrTooManyInputs = errors.New("witnesses: witness elements")

	// ErrByteSliceTooLarge is returned when an encoded byte slice is too
	// large.
	ErrByteSliceTooLarge = errors.New("bytes: too large")

	// ErrDuplicateScriptKeys is returned when two alt leaves have the same
	// script key.
	ErrDuplicateScriptKeys = errors.New("alt leaf: duplicate script keys")
)
View Source
var (
	VersionGen = rapid.SampledFrom([]Version{V0, V1})

	// This is used for fields that are uint64, but clamped to UINT32_MAX
	// by other checks at runtime.
	NonZeroUint32Gen  = rapid.Uint64Range(1, math.MaxUint32)
	HashBytesGen      = NewByteSliceGen(sha256.Size)
	WitnessElementGen = rapid.SliceOfN(
		rapid.Byte(), 1, MaxTxWitnessElementSize,
	)
	AssetIDGen = rapid.Custom(func(t *rapid.T) ID {
		return (ID)(HashBytesGen.Draw(t, "asset_id"))
	})
	OutPointGen = rapid.Make[wire.OutPoint]()

	PrivKeyGen = rapid.Custom(PrivKeyInnerGen)
	PubKeyGen  = rapid.Custom(func(t *rapid.T) *btcec.PublicKey {
		return PrivKeyGen.Draw(t, "privkey").PubKey()
	})
	MaybePubKeyGen = rapid.OneOf(
		PubKeyGen, rapid.Just[*btcec.PublicKey](nil),
	)
	KeyLocGen = rapid.Custom(func(t *rapid.T) keychain.KeyLocator {
		keyFam := rapid.Uint32().Draw(t, "key_family")

		return keychain.KeyLocator{
			Family: keychain.KeyFamily(keyFam),
			Index:  rapid.Uint32().Draw(t, "key_index"),
		}
	})
	KeyDescGen = rapid.Custom(func(t *rapid.T) keychain.KeyDescriptor {
		return keychain.KeyDescriptor{
			KeyLocator: KeyLocGen.Draw(t, "key_locator"),
			PubKey:     MaybePubKeyGen.Draw(t, "pubkey"),
		}
	})
	TweakedScriptKeyGen = rapid.Custom(func(t *rapid.T) TweakedScriptKey {
		return TweakedScriptKey{
			RawKey:        KeyDescGen.Draw(t, "raw_key"),
			Tweak:         HashBytesGen.Draw(t, "tweak"),
			DeclaredKnown: rapid.Bool().Draw(t, "declared_known"),
		}
	})
	ScriptKeyGen = rapid.Custom(func(t *rapid.T) ScriptKey {
		return ScriptKey{
			PubKey: MaybePubKeyGen.Draw(t, "pubkey"),
			TweakedScriptKey: rapid.Ptr(
				TweakedScriptKeyGen, true,
			).Draw(t, "tweaked_script_key"),
		}
	})
	SerializedKeyGen = rapid.Custom(func(t *rapid.T) SerializedKey {
		key := PubKeyGen.Draw(t, "serialized_key")
		return ToSerialized(key)
	})

	// All TxWitness will have at least 1 element of 1 byte, or be nil. This
	// helps us avoid failed equality checks for []byte{} and nil.
	TxWitnessGen = rapid.Custom(func(t *rapid.T) wire.TxWitness {
		witness := rapid.SliceOfN(
			WitnessElementGen, 1, MaxTxWitnessElementCount,
		).Draw(t, "tx_witness_non_empty")

		return rapid.SampledFrom(
			[]wire.TxWitness{witness, nil},
		).Draw(t, "tx_witness")
	})
	NonGenesisPrevIDGen = rapid.Custom(func(t *rapid.T) PrevID {
		return PrevID{
			OutPoint:  OutPointGen.Draw(t, "outpoint"),
			ID:        AssetIDGen.Draw(t, "asset_id"),
			ScriptKey: SerializedKeyGen.Draw(t, "script_key"),
		}
	})
	GenesisGen = rapid.Custom(func(t *rapid.T) Genesis {
		return Genesis{
			FirstPrevOut: OutPointGen.Draw(t, "first_prev_out"),
			Tag: rapid.StringN(
				-1, -1, MaxAssetNameLength,
			).Draw(t, "tag"),
			MetaHash: rapid.Make[[32]byte]().Draw(
				t, "meta_hash",
			),
			OutputIndex: rapid.Uint32().Draw(t, "output_index"),
			Type: Type(rapid.IntRange(0, 1).Draw(
				t, "asset_type"),
			),
		}
	})
	SplitRootGen = rapid.Custom(func(t *rapid.T) mssmt.BranchNode {
		return *mssmt.NewComputedBranch(
			mssmt.NodeHash(HashBytesGen.Draw(t, "split_root_hash")),
			NonZeroUint32Gen.Draw(t, "split_root_sum"),
		)
	})
	WitnessGen = rapid.Custom(func(t *rapid.T) Witness {
		randomPrevID := NonGenesisPrevIDGen.Draw(t, "prev_id")

		prevID := rapid.SampledFrom(
			[]*PrevID{&randomPrevID, {}},
		)

		return Witness{
			PrevID:    prevID.Draw(t, "witness prevID"),
			TxWitness: TxWitnessGen.Draw(t, "tx_witness"),

			SplitCommitment: nil,
		}
	})
	PrevWitnessGen = rapid.SliceOfN(WitnessGen, 0, MaxPrevWitnesses)
	AssetGen       = rapid.Custom(AssetInnerGen)
)
View Source
var (
	// ErrTreeNotFound is returned when a TapscriptTreeManager attempts to
	// load a Tapscript tree, but found no tree nodes.
	ErrTreeNotFound = errors.New("tapscript tree not found")

	// ErrInvalidTapBranch is returned when decoding a slice of byte slices
	// to a TapBranch, and there are not exactly two slices.
	ErrInvalidTapBranch = errors.New(
		"tapscript tree branch must be 2 nodes",
	)
)

KnownAssetLeafTypes is a set of all known asset leaf TLV types. This set is asserted to be complete by a check in the BIP test vector unit tests.

Functions

func AddLeafKeysVerifyUnique added in v0.5.0

func AddLeafKeysVerifyUnique(existingKeys LeafKeySet,
	leaves []AltLeaf[Asset]) error

AddLeafKeysVerifyUnique checks that a set of Assets are valid AltLeaves, and have unique AssetCommitmentKeys (unique among the given slice but also not colliding with any of the keys in the existingKeys set). If the leaves are valid, the function returns the updated set of keys.

func AltLeafGen added in v0.5.0

func AltLeafGen(t *rapid.T) *rapid.Generator[Asset]

AltLeafGen generates an Asset with mostly random fields. The generators for specific fields choose between a random value and a known valid value for an Asset that would be an AltLeaf.

func AltLeavesDecoder added in v0.5.0

func AltLeavesDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func AltLeavesEncoder added in v0.5.0

func AltLeavesEncoder(w io.Writer, val any, buf *[8]byte) error

func AssertNoUnknownEvenTypes added in v0.5.0

func AssertNoUnknownEvenTypes(parsedTypes tlv.TypeMap,
	knownTypes fn.Set[tlv.Type]) error

AssertNoUnknownEvenTypes asserts that the given parsed types do not contain any unknown types. We only care if there's an even type that we don't know of, adopting the same strategy as the BOLTS do ("it's okay to be odd"), meaning that odd types are optional and therefore can be allowed to be unknown. If we find an unknown even type, then it means we're behind in our software version and an error is returned detailing the type.

func AssetCommitmentKey

func AssetCommitmentKey(assetID ID, scriptKey *btcec.PublicKey,
	issuanceDisabled bool) [32]byte

AssetCommitmentKey returns a key which can be used to locate an asset within an AssetCommitment that is specific to a particular owner (script key).

NOTE: This function is also used outside the asset package.

func BranchNodesRootHash added in v0.4.0

func BranchNodesRootHash(b TapBranchNodes) chainhash.Hash

BranchNodesRootHash returns the root hash of a Tapscript tree built from the tapHashes stored in a TapBranchNodes object.

func CheckAssetAsserts added in v0.5.0

func CheckAssetAsserts(a *Asset, checks ...AssetAssert) error

CheckAssetAsserts runs a series of asset assertions and propagates an error if any of them fail.

func CheckTapLeafSanity added in v0.4.0

func CheckTapLeafSanity(leaf *txscript.TapLeaf) error

CheckTapLeafSanity asserts that a TapLeaf script is smaller than the maximum witness size, and that the TapLeaf version is Tapscript v0.

func CheckTapLeavesSanity added in v0.4.0

func CheckTapLeavesSanity(leaves []txscript.TapLeaf) error

CheckTapLeavesSanity asserts that a slice of TapLeafs is below the maximum size, and that each leaf passes a sanity check for script version and size.

func CombineRecords added in v0.5.0

func CombineRecords(records []tlv.Record, unparsed tlv.TypeMap) []tlv.Record

CombineRecords returns a new slice of records that combines the given records with the unparsed types converted to static records.

func CompareAltLeaves added in v0.5.0

func CompareAltLeaves(t *testing.T, a, b []AltLeaf[Asset])

CompareAltLeaves compares two slices of AltLeafAssets for equality.

func CompressedPubKeyDecoder

func CompressedPubKeyDecoder(r io.Reader, val any, buf *[8]byte,
	l uint64) error

func CompressedPubKeyEncoder

func CompressedPubKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func ComputeTaprootScript added in v0.3.0

func ComputeTaprootScript(witnessProgram []byte) ([]byte, error)

ComputeTaprootScript computes the on-chain SegWit v1 script, known as Taproot, based on the given `witnessProgram`.

func DVarBytesWithLimit added in v0.3.0

func DVarBytesWithLimit(limit uint64) tlv.Decoder

func DecodeTapLeaf added in v0.4.0

func DecodeTapLeaf(leafData []byte) (*txscript.TapLeaf, error)

DecodeTapLeaf decodes a byte slice containing a TapLeaf TLV record prefixed with a varint indicating the length of the record.

func DeriveBurnKey added in v0.3.0

func DeriveBurnKey(firstPrevID PrevID) *btcec.PublicKey

DeriveBurnKey derives a provably un-spendable but unique key by tweaking the public NUMS key with a tap tweak:

burnTweak = h_tapTweak(NUMSKey || outPoint || assetID || scriptKey)
burnKey = NUMSKey + burnTweak*G

The firstPrevID must be the PrevID from the first input that is being spent by the virtual transaction that contains the burn.

func EncodeTapBranchNodes added in v0.4.0

func EncodeTapBranchNodes(branch TapBranchNodes) [][]byte

func EncodeTapLeaf added in v0.4.0

func EncodeTapLeaf(leaf *txscript.TapLeaf) ([]byte, error)

EncodeTapLeaf encodes a TapLeaf into a byte slice containing a TapLeaf TLV record, prefixed with a varint indicating the length of the record.

func EncodeTapLeafNodes added in v0.4.0

func EncodeTapLeafNodes(leaves TapLeafNodes) ([][]byte, error)

func EqualKeyDescriptors

func EqualKeyDescriptors(a, o keychain.KeyDescriptor) bool

EqualKeyDescriptors returns true if the two key descriptors are equal.

func FilterUnknownTypes added in v0.5.0

func FilterUnknownTypes(parsedTypes tlv.TypeMap,
	knownTypes fn.Set[tlv.Type]) tlv.TypeMap

FilterUnknownTypes filters out all types that are unknown from the given parsed types. The known types are specified as a set.

func GenesisDecoder

func GenesisDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func GenesisEncoder

func GenesisEncoder(w io.Writer, val any, buf *[8]byte) error

func GenesisPrevOutFetcher added in v0.3.0

func GenesisPrevOutFetcher(prevAsset Asset) (*txscript.CannedPrevOutputFetcher,
	error)

GenesisPrevOutFetcher returns a Taproot Asset input's `PrevOutFetcher` to be used throughout signing when the input asset is a genesis grouped asset.

func GetBranch added in v0.4.0

GetBranch returns an Option containing a copy of the internal TapBranchNodes, if it exists.

func GetLeaves added in v0.4.0

func GetLeaves(ttn TapscriptTreeNodes) fn.Option[TapLeafNodes]

GetLeaves returns an Option containing a copy of the internal TapLeafNodes, if it exists.

func GroupKeyDecoder

func GroupKeyDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func GroupKeyEncoder

func GroupKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func GroupKeyRevealDecoder added in v0.5.0

func GroupKeyRevealDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func GroupKeyRevealEncoder added in v0.5.0

func GroupKeyRevealEncoder(w io.Writer, val any, _ *[8]byte) error

func GroupPubKeyV0 added in v0.5.0

func GroupPubKeyV0(rawKey *btcec.PublicKey, singleTweak, tapTweak []byte) (
	*btcec.PublicKey, error)

GroupPubKeyV0 derives a version 0 tweaked group key from a public key and two tweaks; the single tweak is the asset ID of the group anchor asset, and the tapTweak is the root of a tapscript tree that commits to script-based conditions for reissuing assets as part of this asset group. The tweaked key is defined by:

internalKey = rawKey + singleTweak * G
tweakedGroupKey = TapTweak(internalKey, tapTweak)

func GroupPubKeyV1 added in v0.5.0

func GroupPubKeyV1(internalKey *btcec.PublicKey,
	tapscriptTree GroupKeyRevealTapscript, assetID ID) (*btcec.PublicKey,
	error)

GroupPubKeyV1 derives a version 1 asset group key from a signing public key and a tapscript tree.

func IDDecoder

func IDDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func IDEncoder

func IDEncoder(w io.Writer, val any, buf *[8]byte) error

func InlineVarBytesDecoder added in v0.3.0

func InlineVarBytesDecoder(r io.Reader, val any, buf *[8]byte,
	maxLen uint64) error

func InlineVarBytesEncoder added in v0.3.0

func InlineVarBytesEncoder(w io.Writer, val any, buf *[8]byte) error

func InputGenesisAssetPrevOut added in v0.3.0

func InputGenesisAssetPrevOut(prevAsset Asset) (*wire.TxOut, error)

InputGenesisAssetPrevOut returns a TxOut that represents the input asset in a Taproot Asset virtual TX, but uses tweaked group key of the input asset to enable group witness validation.

func IsBurnKey added in v0.3.0

func IsBurnKey(scriptKey *btcec.PublicKey, witness Witness) bool

IsBurnKey returns true if the given script key is a valid burn key for the given witness.

func IsGroupSig added in v0.3.0

func IsGroupSig(witness wire.TxWitness) (*schnorr.Signature, bool)

IsGroupSig checks if the given witness represents a key path spend of the tweaked group key. Such a witness must include one Schnorr signature, and can include an optional annex (matching the rules specified in BIP-341). If the signature is valid, IsGroupSig returns true and the parsed signature.

func IsSplitCommitWitness added in v0.3.0

func IsSplitCommitWitness(witness Witness) bool

IsSplitCommitWitness returns true if the witness is a split-commitment witness.

func LeafDecoder

func LeafDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func LeafEncoder

func LeafEncoder(w io.Writer, val any, buf *[8]byte) error

func LeafNodesRootHash added in v0.4.0

func LeafNodesRootHash(l TapLeafNodes) chainhash.Hash

LeafNodesRootHash returns the root hash of a Tapscript tree built from the TapLeaf nodes in a TapLeafNodes object.

func NewByteSliceGen added in v0.5.0

func NewByteSliceGen(p int) *rapid.Generator[[]byte]

NewByteSliceGen constructs a generator for []byte that will always create fully populated slices of length p.

func NewGKRCustomSubtreeRootRecord added in v0.5.0

func NewGKRCustomSubtreeRootRecord(root *chainhash.Hash) tlv.Record

func NewGKRInternalKeyRecord added in v0.5.0

func NewGKRInternalKeyRecord(internalKey *SerializedKey) tlv.Record

func NewGKRTapscriptRootRecord added in v0.5.0

func NewGKRTapscriptRootRecord(root *chainhash.Hash) tlv.Record

func NewGKRVersionRecord added in v0.5.0

func NewGKRVersionRecord(version *uint8) tlv.Record

func NewGroupKeyV1FromExternal added in v0.5.1

func NewGroupKeyV1FromExternal(version NonSpendLeafVersion,
	externalKey ExternalKey, assetID ID,
	customRoot fn.Option[chainhash.Hash]) (btcec.PublicKey, chainhash.Hash,
	error)

NewGroupKeyV1FromExternal creates a new V1 group key from an external key and asset ID. The customRootHash is optional and can be used to specify a custom tapscript root.

func NewLeafAmountRecord

func NewLeafAmountRecord(amount *uint64) tlv.Record

func NewLeafGenesisRecord

func NewLeafGenesisRecord(genesis *Genesis) tlv.Record

func NewLeafGroupKeyRecord

func NewLeafGroupKeyRecord(groupKey **GroupKey) tlv.Record

func NewLeafLockTimeRecord

func NewLeafLockTimeRecord(lockTime *uint64) tlv.Record

func NewLeafPrevWitnessRecord

func NewLeafPrevWitnessRecord(prevWitnesses *[]Witness,
	encodeType EncodeType) tlv.Record

func NewLeafRelativeLockTimeRecord

func NewLeafRelativeLockTimeRecord(relativeLockTime *uint64) tlv.Record

func NewLeafScriptKeyRecord

func NewLeafScriptKeyRecord(scriptKey **btcec.PublicKey) tlv.Record

func NewLeafScriptVersionRecord

func NewLeafScriptVersionRecord(version *ScriptVersion) tlv.Record

func NewLeafSplitCommitmentRootRecord

func NewLeafSplitCommitmentRootRecord(root *mssmt.Node) tlv.Record

func NewLeafTypeRecord

func NewLeafTypeRecord(assetType *Type) tlv.Record

func NewLeafVersionRecord

func NewLeafVersionRecord(version *Version) tlv.Record

func NewNonSpendableScriptLeaf added in v0.5.0

func NewNonSpendableScriptLeaf(version NonSpendLeafVersion,
	data []byte) (txscript.TapLeaf, error)

NewNonSpendableScriptLeaf creates a new non-spendable tapscript script leaf that includes the specified data. If the data is nil, the leaf will not contain any data but will still be a valid non-spendable script leaf.

The script leaf is made non-spendable by including an OP_RETURN at the start of the script (or an OP_CHECKSIG at the end, depending on the version). While the script can still be executed, it will always fail and cannot be used to spend funds.

func NewTapBranchHash added in v0.4.0

func NewTapBranchHash(l, r chainhash.Hash) chainhash.Hash

NewTapBranchHash takes the raw tap hashes of the left and right nodes and hashes them into a branch.

func NewWitnessPrevIDRecord

func NewWitnessPrevIDRecord(prevID **PrevID) tlv.Record

func NewWitnessSplitCommitmentRecord

func NewWitnessSplitCommitmentRecord(commitment **SplitCommitment) tlv.Record

func NewWitnessTxWitnessRecord

func NewWitnessTxWitnessRecord(witness *wire.TxWitness) tlv.Record

func NumsXPub added in v0.5.1

func NumsXPub(numsKey btcec.PublicKey) (*hdkeychain.ExtendedKey,
	*btcec.PublicKey, error)

NumsXPub turns the given NUMS key into an extended public key (using the x coordinate of the public key as the chain code), then derives the actual key to use from the derivation path 0/0. The extended key always has the mainnet version, but can be converted to any network on demand by the caller with CloneWithVersion().

func OutPointDecoder

func OutPointDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func OutPointEncoder

func OutPointEncoder(w io.Writer, val any, buf *[8]byte) error

func ParseGroupSig added in v0.3.0

func ParseGroupSig(witness []byte) (*schnorr.Signature, error)

ParseGroupSig parses a group signature that was stored as a group witness in the DB. It returns an error if the witness is not a single Schnorr signature.

func ParseGroupWitness added in v0.3.0

func ParseGroupWitness(witness []byte) (wire.TxWitness, error)

ParseGroupWitness parses a group witness that was stored as a TLV stream in the DB.

func PrevIDDecoder

func PrevIDDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func PrevIDEncoder

func PrevIDEncoder(w io.Writer, val any, buf *[8]byte) error

func PrivKeyInnerGen added in v0.5.0

func PrivKeyInnerGen(t *rapid.T) *btcec.PrivateKey

PrivKeyInnerGen generates a valid, random secp256k1 private key for use in property tests.

func SchnorrSignatureDecoder

func SchnorrSignatureDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SchnorrSignatureEncoder

func SchnorrSignatureEncoder(w io.Writer, val any, buf *[8]byte) error

func ScriptVersionDecoder

func ScriptVersionDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func ScriptVersionEncoder

func ScriptVersionEncoder(w io.Writer, val any, buf *[8]byte) error

func SerializeGroupWitness added in v0.3.0

func SerializeGroupWitness(witness wire.TxWitness) ([]byte, error)

SerializeGroupWitness serializes a group witness into a TLV stream suitable for storing in the DB.

func SerializedKeyDecoder

func SerializedKeyDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SerializedKeyEncoder

func SerializedKeyEncoder(w io.Writer, val any, buf *[8]byte) error

func SignOutputRaw added in v0.3.0

func SignOutputRaw(priv *btcec.PrivateKey, tx *wire.MsgTx,
	signDesc *input.SignDescriptor) (*schnorr.Signature, error)

SignOutputRaw creates a signature for a single input. Taken from lnd/lnwallet/btcwallet/signer:L344, SignOutputRaw

func SignVirtualTx added in v0.3.0

func SignVirtualTx(priv *btcec.PrivateKey, signDesc *lndclient.SignDescriptor,
	tx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature, error)

func SortFunc added in v0.5.0

func SortFunc(a, b *Asset) int

SortFunc is used to sort assets lexicographically by their script keys.

func SplitCommitmentDecoder

func SplitCommitmentDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SplitCommitmentEncoder

func SplitCommitmentEncoder(w io.Writer, val any, buf *[8]byte) error

func SplitCommitmentRootDecoder

func SplitCommitmentRootDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func SplitCommitmentRootEncoder

func SplitCommitmentRootEncoder(w io.Writer, val any, buf *[8]byte) error

func TapBranchHash added in v0.5.0

func TapBranchHash(l, r chainhash.Hash) chainhash.Hash

TapBranchHash takes the tap hashes of the left and right nodes and hashes them into a branch.

func TapCommitmentKey

func TapCommitmentKey(assetSpecifier Specifier) [32]byte

TapCommitmentKey is the key that maps to the root commitment for a specific asset within a TapCommitment.

NOTE: This function is also used outside the asset package.

func TlvStrictDecode added in v0.5.0

func TlvStrictDecode(stream *tlv.Stream, r io.Reader,
	knownTypes fn.Set[tlv.Type]) (tlv.TypeMap, error)

TlvStrictDecode attempts to decode the passed buffer into the TLV stream. It takes the set of known types for a given stream, and returns an error if the buffer includes any unknown even types.

func TlvStrictDecodeP2P added in v0.5.0

func TlvStrictDecodeP2P(stream *tlv.Stream, r io.Reader,
	knownTypes fn.Set[tlv.Type]) (tlv.TypeMap, error)

TlvStrictDecodeP2P is identical to TlvStrictDecode except that the record size is capped at 65535. This should only be called from a p2p setting where untrusted input is being deserialized.

func ToBranch added in v0.4.0

func ToBranch(b TapBranchNodes) [][]byte

ToBranch returns an encoded TapBranchNodes object.

func ToLeaves added in v0.4.0

func ToLeaves(l TapLeafNodes) []txscript.TapLeaf

ToLeaves returns the TapLeaf slice inside a TapLeafNodes object.

func TweakedNumsKey added in v0.5.1

func TweakedNumsKey(msg [32]byte) (*hdkeychain.ExtendedKey, *btcec.PublicKey,
	error)

TweakedNumsKey derives the NUMS key from the given data, then creates the extended key from it and derives the actual (derived child) key to use from the derivation path 0/0. The extended key always has the mainnet version, but can be converted to any network on demand by the caller with CloneWithVersion().

func TxWitnessDecoder

func TxWitnessDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func TxWitnessEncoder

func TxWitnessEncoder(w io.Writer, val any, buf *[8]byte) error

func TypeDecoder

func TypeDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func TypeEncoder

func TypeEncoder(w io.Writer, val any, buf *[8]byte) error

func ValidAltLeaves added in v0.5.0

func ValidAltLeaves(leaves []AltLeaf[Asset]) error

ValidAltLeaves checks that a set of Assets are valid AltLeaves, and can be used to construct an AltCommitment. This requires that each AltLeaf has a unique AssetCommitmentKey.

func ValidateAssetName added in v0.3.0

func ValidateAssetName(name string) error

ValidateAssetName validates an asset name (the asset's genesis tag).

func VarIntDecoder

func VarIntDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func VarIntEncoder

func VarIntEncoder(w io.Writer, val any, buf *[8]byte) error

func VersionDecoder

func VersionDecoder(r io.Reader, val any, buf *[8]byte, l uint64) error

func VersionEncoder

func VersionEncoder(w io.Writer, val any, buf *[8]byte) error

func VirtualGenesisTxIn added in v0.3.0

func VirtualGenesisTxIn(newAsset *Asset) (*wire.TxIn, mssmt.Tree, error)

VirtualGenesisTxIn computes the single input of a Taproot Asset virtual transaction that represents a grouped asset genesis. The input prevout's hash is the root of a MS-SMT committing to only the genesis asset.

func VirtualTxInPrevOut added in v0.3.0

func VirtualTxInPrevOut(root mssmt.Node) *wire.OutPoint

VirtualTxInPrevOut returns the prevout of the Taproot Asset virtual transaction's single input as a hash of the root node's key concatenated by its sum.

func VirtualTxWithInput added in v0.3.0

func VirtualTxWithInput(virtualTx *wire.MsgTx, lockTime,
	relativeLockTime uint64, idx uint32,
	witness wire.TxWitness) *wire.MsgTx

VirtualTxWithInput returns a copy of the `virtualTx` amended to include all input-specific details.

This is used to further bind a given witness to the "true" input it spends. We'll use the index of the serialized input to bind the prev index, which represents the "leaf index" of the virtual input MS-SMT.

func WitnessDecoder

func WitnessDecoder(r io.Reader, val any, buf *[8]byte, _ uint64) error

func WitnessEncoder

func WitnessEncoder(w io.Writer, val any, buf *[8]byte) error

func WitnessEncoderWithType added in v0.3.0

func WitnessEncoderWithType(encodeType EncodeType) tlv.Encoder

WitnessEncoderWithType is a wrapper around WitnessEncoder that allows the caller to specify th witness type. It's a higher order function that returns an encoder function.

Types

type AltLeaf added in v0.5.0

type AltLeaf[T any] interface {
	// Copyable asserts that the target type of this interface satisfies
	// the Copyable interface.
	fn.Copyable[*T]

	// AssetCommitmentKey is the key for an AltLeaf within an
	// AssetCommitment.
	AssetCommitmentKey() [32]byte

	// ValidateAltLeaf ensures that an AltLeaf is valid.
	ValidateAltLeaf() error

	// EncodeAltLeaf encodes an AltLeaf into a TLV stream.
	EncodeAltLeaf(w io.Writer) error

	// DecodeAltLeaf decodes an AltLeaf from a TLV stream.
	DecodeAltLeaf(r io.Reader) error
}

An AltLeaf is a type that is used to carry arbitrary data, and does not represent a Taproot asset. An AltLeaf can be used to anchor other protocols alongside Taproot Asset transactions.

func CopyAltLeaves added in v0.5.0

func CopyAltLeaves(a []AltLeaf[Asset]) []AltLeaf[Asset]

CopyAltLeaves performs a deep copy of an AltLeaf slice.

func ToAltLeaves added in v0.5.0

func ToAltLeaves(leaves []*Asset) []AltLeaf[Asset]

ToAltLeaves casts []Asset to []AltLeafAsset, without checking that the assets are valid AltLeaves.

type Asset

type Asset struct {
	// Version is the Taproot Asset version of the asset.
	Version Version

	// Genesis encodes an asset's genesis metadata which directly maps to
	// its unique ID within the Taproot Asset protocol.
	Genesis

	// Amount is the number of units represented by the asset.
	Amount uint64

	// LockTime, if non-zero, restricts an asset from being moved prior to
	// the represented block height in the chain. This value needs to be set
	// on the asset that is spending from a script key with a CLTV script.
	LockTime uint64

	// RelativeLockTime, if non-zero, restricts an asset from being moved
	// until a number of blocks after the confirmation height of the latest
	// transaction for the asset is reached. This value needs to be set
	// on the asset that is spending from a script key with a CSV script.
	RelativeLockTime uint64

	// PrevWitnesses contains the witness(es) of an asset's previous
	// transfer.
	PrevWitnesses []Witness

	// SplitCommitmentRoot is the root node of the MS-SMT storing split
	// commitments.
	//
	// NOTE: This should only be set when the previous transfer of an asset
	// resulted in a value split.
	SplitCommitmentRoot mssmt.Node

	// ScriptVersion denotes how an asset's ScriptKey should be validated.
	ScriptVersion ScriptVersion

	// ScriptKey represents a tweaked Taproot output key encumbering the
	// different ways an asset can be spent.
	ScriptKey ScriptKey

	// GroupKey is the tweaked public key that is used to associate assets
	// together across distinct asset IDs, allowing further issuance of the
	// asset to be made possible.
	GroupKey *GroupKey

	// UnknownOddTypes is a map of unknown odd types that were encountered
	// during decoding. This map is used to preserve unknown types that we
	// don't know of yet, so we can still encode them back when serializing
	// as a leaf to arrive at the same byte representation and with that
	// same commitment root hash. This enables forward compatibility with
	// future versions of the protocol as it allows new odd (optional) types
	// to be added without breaking old clients that don't yet fully
	// understand them.
	UnknownOddTypes tlv.TypeMap
}

Asset represents a Taproot asset.

func AssetCustomGroupKey added in v0.4.0

func AssetCustomGroupKey(t *testing.T, useHashLock, BIP86, keySpend,
	validScriptWitness bool, gen Genesis) *Asset

AssetCustomGroupKey constructs a new asset group key and anchor asset from a given asset genesis. The asset group key may also commit to a Tapscript tree root. The tree used in that case includes a hash lock and signature lock. The validity of that Tapscript tree is set by the caller.

The following group key derivation methods are supported:

BIP86: The group key commits to an empty tapscript tree. Assets can only be added to the group with a valid signature from the tweaked group key.

Key-spend: The group key commits to a tapscript tree root, but the witness for the group anchor will be a signature using the tweaked group key. Assets could later be added to the group with either a signature from the tweaked group key or a valid witness for a script in the committed tapscript tree.

Script-spend: The group key commits to a tapscript tree root, and the witness for the group anchor is a valid script witness for a script in the tapscript tree. Assets could later be added to the group with either a signature from the tweaked group key or a valid witness for a script in the committed tapscript tree.

func AssetGenWithValues added in v0.5.0

func AssetGenWithValues(t *rapid.T, genesis Genesis, groupKey *GroupKey,
	scriptKey ScriptKey) *Asset

AssetGenWithValues generates an Asset with some specific fields set.

func AssetInnerGen added in v0.5.0

func AssetInnerGen(t *rapid.T) Asset

AssetInnerGen generates an Asset with random fields, that may also have a valid group key.

func FromAltLeaves added in v0.5.0

func FromAltLeaves(leaves []AltLeaf[Asset]) []*Asset

FromAltLeaves casts []AltLeafAsset to []Asset, which is always safe.

func New

func New(genesis Genesis, amount, locktime, relativeLocktime uint64,
	scriptKey ScriptKey, groupKey *GroupKey,
	opts ...NewAssetOpt) (*Asset, error)

New instantiates a new asset with a genesis asset witness.

func NewAltLeaf added in v0.5.0

func NewAltLeaf(key ScriptKey, keyVersion ScriptVersion,
	prevWitness []Witness) (*Asset, error)

NewAltLeaf instantiates a new valid AltLeaf.

func NewAssetNoErr added in v0.3.0

func NewAssetNoErr(t testing.TB, gen Genesis, amt, locktime, relocktime uint64,
	scriptKey ScriptKey, groupKey *GroupKey, opts ...NewAssetOpt) *Asset

NewAssetNoErr creates an asset and fails the test if asset creation fails.

func RandAltLeaf added in v0.5.0

func RandAltLeaf(t testing.TB) *Asset

RandAltLeaf generates a random Asset that is a valid AltLeaf.

func RandAltLeaves added in v0.5.0

func RandAltLeaves(t testing.TB, nonZero bool) []*Asset

RandAltLeaves generates a random number of random alt leaves.

func RandAsset

func RandAsset(t testing.TB, assetType Type) *Asset

RandAsset creates a random asset of the given type for testing.

func RandAssetWithValues

func RandAssetWithValues(t testing.TB, genesis Genesis, groupKey *GroupKey,
	scriptKey ScriptKey) *Asset

RandAssetWithValues creates a random asset with the given genesis and keys for testing.

func (*Asset) AssetCommitmentKey

func (a *Asset) AssetCommitmentKey() [32]byte

AssetCommitmentKey is the key that maps to a specific owner of an asset within a Taproot AssetCommitment.

func (*Asset) Copy

func (a *Asset) Copy() *Asset

Copy returns a deep copy of an Asset.

func (*Asset) CopySpendTemplate added in v0.5.0

func (a *Asset) CopySpendTemplate() *Asset

CopySpendTemplate is similar to Copy, but should be used when wanting to spend an input asset in a new transaction. Compared to Copy, this method also blanks out some other fields that shouldn't always be carried along for a dependent spend.

func (*Asset) Decode

func (a *Asset) Decode(r io.Reader) error

Decode decodes an asset from a TLV stream.

func (*Asset) DecodeAltLeaf added in v0.5.0

func (a *Asset) DecodeAltLeaf(r io.Reader) error

DecodeAltLeaf decodes an AltLeaf from a TLV stream. The normal Asset decoder can be reused here, since any Asset field not encoded in the AltLeaf will be set to its default value, which matches the AltLeaf validity constraints.

func (*Asset) DecodeRecords

func (a *Asset) DecodeRecords() []tlv.Record

DecodeRecords provides all records known for an asset witness for proper decoding.

func (*Asset) DeepEqual

func (a *Asset) DeepEqual(o *Asset) bool

DeepEqual returns true if this asset is equal with the given asset.

func (*Asset) DeepEqualAllowSegWitIgnoreTxWitness added in v0.4.0

func (a *Asset) DeepEqualAllowSegWitIgnoreTxWitness(o *Asset) bool

DeepEqualAllowSegWitIgnoreTxWitness returns true if this asset is equal with the given asset, ignoring the TxWitness field of the Witness if the asset version is v1.

func (*Asset) Encode

func (a *Asset) Encode(w io.Writer) error

Encode encodes an asset into a TLV stream. This is used for encoding proof files and state transitions.

func (*Asset) EncodeAltLeaf added in v0.5.0

func (a *Asset) EncodeAltLeaf(w io.Writer) error

EncodeAltLeaf encodes an AltLeaf into a TLV stream.

func (*Asset) EncodeNoWitness added in v0.3.0

func (a *Asset) EncodeNoWitness(w io.Writer) error

EncodeNoWitness encodes the asset without the witness into a TLV stream. This is used for serializing on an asset as a leaf within a TAP MS-SMT tree. This only applies when the asset version is v1.

func (*Asset) EncodeRecords

func (a *Asset) EncodeRecords() []tlv.Record

EncodeRecords determines the non-nil records to include when encoding an asset at runtime.

func (*Asset) HasGenesisWitness

func (a *Asset) HasGenesisWitness() bool

HasGenesisWitness determines whether an asset has a valid genesis witness, which should only have one input with a zero PrevID and empty witness and split commitment proof.

func (*Asset) HasGenesisWitnessForGroup added in v0.3.0

func (a *Asset) HasGenesisWitnessForGroup() bool

HasGenesisWitnessForGroup determines whether an asset has a witness for a genesis asset in an asset group. This asset must have a non-empty group key and a single prevWitness with a zero PrevID, empty split commitment proof, and non-empty witness.

func (*Asset) HasSplitCommitmentWitness

func (a *Asset) HasSplitCommitmentWitness() bool

HasSplitCommitmentWitness returns true if an asset has a split commitment witness.

func (*Asset) IsAltLeaf added in v0.5.0

func (a *Asset) IsAltLeaf() bool

IsAltLeaf returns true if an Asset would be stored in the AltCommitment of a TapCommitment. It does not check if the Asset is a valid AltLeaf.

func (*Asset) IsBurn added in v0.3.0

func (a *Asset) IsBurn() bool

IsBurn returns true if an asset uses an un-spendable script key that was constructed using the proof-of-burn scheme.

func (*Asset) IsGenesisAsset added in v0.3.0

func (a *Asset) IsGenesisAsset() bool

IsGenesisAsset returns true if an asset is a genesis asset.

func (*Asset) IsUnSpendable

func (a *Asset) IsUnSpendable() bool

IsUnSpendable returns true if an asset uses the un-spendable script key and has zero value.

func (*Asset) IsUnknownVersion added in v0.3.0

func (a *Asset) IsUnknownVersion() bool

IsUnknownVersion returns true if an asset has a version that is not recognized by this implementation of tap.

func (*Asset) Leaf

func (a *Asset) Leaf() (*mssmt.LeafNode, error)

Leaf returns the asset encoded as a MS-SMT leaf node.

func (*Asset) NeedsGenesisWitnessForGroup added in v0.3.0

func (a *Asset) NeedsGenesisWitnessForGroup() bool

NeedsGenesisWitnessForGroup determines whether an asset is a genesis grouped asset, which does not yet have a group witness.

func (*Asset) PrimaryPrevID added in v0.3.0

func (a *Asset) PrimaryPrevID() (*PrevID, error)

PrimaryPrevID returns the primary prev ID of an asset. This is the prev ID of the first witness, unless the first witness is a split-commitment witness, in which case it is the prev ID of the first witness of the root asset. The first witness effectively corresponds to the asset's direct lineage.

func (*Asset) Record added in v0.4.0

func (a *Asset) Record() tlv.Record

Record returns a TLV record that can be used to encode/decode an Asset to/from a TLV stream.

NOTE: This is part of the tlv.RecordProducer interface.

func (*Asset) Specifier added in v0.4.0

func (a *Asset) Specifier() Specifier

Specifier returns the asset's specifier.

func (*Asset) TapCommitmentKey

func (a *Asset) TapCommitmentKey() [32]byte

TapCommitmentKey is the key that maps to the root commitment for a specific asset group within a TapCommitment.

func (*Asset) UpdateTxWitness added in v0.4.0

func (a *Asset) UpdateTxWitness(prevWitnessIndex int,
	witness wire.TxWitness) error

UpdateTxWitness updates the transaction witness at the given index with the provided witness stack. The previous witness index references the input that is spent.

func (*Asset) Validate added in v0.3.0

func (a *Asset) Validate() error

Validate ensures that an asset is valid.

func (*Asset) ValidateAltLeaf added in v0.5.0

func (a *Asset) ValidateAltLeaf() error

ValidateAltLeaf checks that an Asset is a valid AltLeaf. An Asset used as an AltLeaf must meet these constraints: - Version must be V0. - Genesis must be the empty Genesis. - Amount, LockTime, and RelativeLockTime must be 0. - SplitCommitmentRoot and GroupKey must be nil. - ScriptKey must be non-nil.

func (*Asset) Witnesses added in v0.4.0

func (a *Asset) Witnesses() []Witness

Witnesses returns the witnesses of an asset. If the asset has a split commitment witness, the witnesses of the root asset are returned.

type AssetAssert added in v0.5.0

type AssetAssert func(a *Asset) error

AssetAssert is a function type that asserts a property of an asset.

func AssetAmountAssert added in v0.5.0

func AssetAmountAssert(amt uint64) AssetAssert

AssetAmountAssert returns an Assert that checks equality for an asset's amount.

func AssetGenesisAssert added in v0.5.0

func AssetGenesisAssert(g Genesis) AssetAssert

AssetGenesisAssert returns an Assert that checks equality for an asset's genesis.

func AssetGroupKeyAssert added in v0.5.0

func AssetGroupKeyAssert(g *GroupKey) AssetAssert

AssetGroupKeyAssert returns an Assert that checks equality for an asset's group key.

func AssetHasScriptKeyAssert added in v0.5.0

func AssetHasScriptKeyAssert(hasKey bool) AssetAssert

AssetHasSplitRootAssert returns an Assert that checks the state of an asset's split commitment root.

func AssetHasSplitRootAssert added in v0.5.0

func AssetHasSplitRootAssert(hasSplit bool) AssetAssert

AssetHasSplitRootAssert returns an Assert that checks the state of an asset's split commitment root.

func AssetLockTimeAssert added in v0.5.0

func AssetLockTimeAssert(l uint64) AssetAssert

AssetLockTimeAssert returns an Assert that checks equality for an asset's lock time.

func AssetRelativeLockTimeAssert added in v0.5.0

func AssetRelativeLockTimeAssert(r uint64) AssetAssert

AssetRelativeLockTimeAssert returns an Assert that checks equality for an asset's relative lock time.

func AssetVersionAssert added in v0.5.0

func AssetVersionAssert(v Version) AssetAssert

AssetVersionAssert returns an Assert that checks equality for an asset's version.

type AssetGroup

type AssetGroup struct {
	*Genesis

	*GroupKey
}

AssetGroup holds information about an asset group, including the genesis information needed re-tweak the raw key.

type BurnTestVectors added in v0.3.0

type BurnTestVectors struct {
	ValidTestCases []*ValidBurnTestCase `json:"valid_test_cases"`
}

type ByteReader added in v0.5.0

type ByteReader struct {
	// contains filtered or unexported fields
}

ByteReader is a wrapper around rapid.T that allows us to use generated random bytes as input for helper functions that require an io.Reader an not []byte.

func NewRapidByteReader added in v0.5.0

func NewRapidByteReader(t *rapid.T, name string, fullRead bool) *ByteReader

NewRapidByteReader returns a new ByteReader ready for use.

func (*ByteReader) Read added in v0.5.0

func (b *ByteReader) Read(p []byte) (n int, err error)

Read implements io.Reader. If fullRead is false for the ByteReader, output of size less than len(p) may be returned.

type ChainAsset added in v0.3.3

type ChainAsset struct {
	*Asset

	// IsSpent indicates whether the above asset was previously spent.
	IsSpent bool

	// AnchorTx is the transaction that anchors this chain asset.
	AnchorTx *wire.MsgTx

	// AnchorBlockHash is the blockhash that mined the anchor tx.
	AnchorBlockHash chainhash.Hash

	// AnchorBlockHeight is the height of the block that mined the anchor
	// tx.
	AnchorBlockHeight uint32

	// AnchorOutpoint is the outpoint that commits to the asset.
	AnchorOutpoint wire.OutPoint

	// AnchorInternalKey is the raw internal key that was used to create the
	// anchor Taproot output key.
	AnchorInternalKey *btcec.PublicKey

	// AnchorMerkleRoot is the Taproot merkle root hash of the anchor output
	// the asset was committed to. If there is no Tapscript sibling, this is
	// equal to the Taproot Asset root commitment hash.
	AnchorMerkleRoot []byte

	// AnchorTapscriptSibling is the serialized preimage of a Tapscript
	// sibling, if there was one. If this is empty, then the
	// AnchorTapscriptSibling hash is equal to the Taproot root hash of the
	// anchor output.
	AnchorTapscriptSibling []byte

	// AnchorLeaseOwner is the identity of the application that currently
	// has a lease on this UTXO. If empty/nil, then the UTXO is not
	// currently leased. A lease means that the UTXO is being
	// reserved/locked to be spent in an upcoming transaction and that it
	// should not be available for coin selection through any of the wallet
	// RPCs.
	AnchorLeaseOwner [32]byte

	// AnchorLeaseExpiry is the expiry of the lease. If the expiry is nil or
	// the time is in the past, then the lease is not valid and the UTXO is
	// available for coin selection.
	AnchorLeaseExpiry *time.Time
}

ChainAsset is a wrapper around the base asset struct that includes information detailing where in the chain the asset is currently anchored.

type ChainLookup added in v0.4.0

type ChainLookup interface {
	// TxBlockHeight returns the block height that the given transaction was
	// included in.
	TxBlockHeight(ctx context.Context, txid chainhash.Hash) (uint32, error)

	// MeanBlockTimestamp returns the timestamp of the block at the given
	// height as a Unix timestamp in seconds, taking into account the mean
	// time elapsed over the previous 10 blocks.
	MeanBlockTimestamp(ctx context.Context, blockHeight uint32) (time.Time,
		error)

	// CurrentHeight returns the current height of the main chain.
	CurrentHeight(context.Context) (uint32, error)
}

ChainLookup is an interface that allows an asset validator to look up certain information about asset related transactions on the backing chain.

type EncodeType added in v0.3.0

type EncodeType uint8

EncodeType is used to denote the type of encoding used for an asset.

const (
	// EncodeNormal normal is the normal encoding type for an asset.
	EncodeNormal EncodeType = iota

	// EncodeSegwit denotes that the witness vector field is not to be
	// encoded.
	EncodeSegwit
)

type ErrUnknownType added in v0.5.0

type ErrUnknownType struct {
	// UnknownType is the type that was unknown.
	UnknownType tlv.Type

	// ValueBytes is the raw bytes of the value that was unknown.
	ValueBytes []byte
}

ErrUnknownType is returned when an unknown type is encountered while decoding a TLV stream.

func (ErrUnknownType) Error added in v0.5.0

func (e ErrUnknownType) Error() string

Error returns the error message for the ErrUnknownType.

type ErrorTestCase added in v0.3.0

type ErrorTestCase struct {
	Asset   *TestAsset `json:"asset"`
	Error   string     `json:"error"`
	Comment string     `json:"comment"`
}

type ExternalKey added in v0.5.1

type ExternalKey struct {
	// XPub is the extended public key derived at depth 3 of the BIP-86
	// hierarchy (e.g., m/86'/0'/0'). This key serves as the parent key for
	// deriving child public keys and addresses.
	XPub hdkeychain.ExtendedKey

	// MasterFingerprint is the fingerprint of the master key, derived from
	// the first 4 bytes of the hash160 of the master public key. It is used
	// to identify the master key in BIP-86 derivation schemes.
	MasterFingerprint uint32

	// DerivationPath specifies the extended BIP-86 derivation path used to
	// derive a child key from the XPub. Starting from the base path of the
	// XPub (e.g., m/86'/0'/0'), this path must contain exactly 5 components
	// in total (e.g., m/86'/0'/0'/0/0), with the additional components
	// defining specific child keys, such as individual addresses.
	DerivationPath []uint32
}

ExternalKey represents an external key used for deriving and managing hierarchical deterministic (HD) wallet addresses according to BIP-86.

func (*ExternalKey) PubKey added in v0.5.1

func (e *ExternalKey) PubKey() (btcec.PublicKey, error)

PubKey derives and returns the public key corresponding to the final index in the ExternalKey's BIP-86 derivation path.

The method assumes the ExternalKey's XPub was derived at depth 3 (e.g., m/86'/0'/0') and uses the fourth and fifth components of the DerivationPath to derive a child key, typically representing an address or output key.

func (*ExternalKey) Validate added in v0.5.1

func (e *ExternalKey) Validate() error

Validate ensures that the ExternalKey's fields conform to the expected requirements for a BIP-86 key structure.

type Genesis

type Genesis struct {
	// FirstPrevOut represents the outpoint of the transaction's first
	// input that resulted in the creation of the asset.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	FirstPrevOut wire.OutPoint

	// Tag is a human-readable identifier for the asset. This does not need
	// to be unique, but asset issuers should attempt for it to be unique if
	// possible. Users usually recognise this field as the asset's name.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	Tag string

	// MetaHash is the hash of the set of encoded meta data. This value is
	// carried along for all assets transferred in the "light cone" of the
	// genesis asset. The preimage for this field may optionally be
	// revealed within the genesis asset proof for this asset.
	//
	// NOTE: This is immutable for the lifetime of the asset.
	MetaHash [MetaHashLen]byte

	// OutputIndex is the index of the output that carries the unique
	// Taproot Asset commitment in the genesis transaction.
	OutputIndex uint32

	// Type uniquely identifies the type of Taproot asset.
	Type Type
}

Genesis encodes an asset's genesis metadata which directly maps to its unique ID within the Taproot Asset protocol.

func DecodeGenesis

func DecodeGenesis(r io.Reader) (Genesis, error)

DecodeGenesis decodes an asset genesis.

func RandGenesis

func RandGenesis(t testing.TB, assetType Type) Genesis

RandGenesis creates a random genesis for testing.

func (Genesis) Encode

func (g Genesis) Encode(w io.Writer) error

Encode encodes an asset genesis.

func (Genesis) ID

func (g Genesis) ID() ID

ID computes an asset's unique identifier from its metadata.

func (Genesis) TagHash

func (g Genesis) TagHash() [sha256.Size]byte

TagHash computes the SHA-256 hash of the asset's tag.

type GenesisSigner

type GenesisSigner interface {
	// SignVirtualTx generates a signature according to the passed signing
	// descriptor and TX.
	SignVirtualTx(signDesc *lndclient.SignDescriptor, tx *wire.MsgTx,
		prevOut *wire.TxOut) (*schnorr.Signature, error)
}

GenesisSigner is used to sign the assetID using the group key public key for a given asset.

type GenesisTxBuilder added in v0.3.0

type GenesisTxBuilder interface {
	// BuildGenesisTx constructs a virtual transaction and prevOut that
	// represent the genesis state transition for a grouped asset. This
	// output is used to create a group witness for the grouped asset.
	BuildGenesisTx(newAsset *Asset) (*wire.MsgTx, *wire.TxOut, error)
}

GenesisTxBuilder is used to construct the virtual transaction that represents asset minting for grouped assets. This transaction is used to generate a group witness that authorizes the minting of an asset into the asset group.

type GroupKey

type GroupKey struct {
	// Version is the version of the group key construction.
	Version GroupKeyVersion

	// RawKey is the raw group key before the tweak with the genesis point
	// has been applied.
	RawKey keychain.KeyDescriptor

	// GroupPubKey is the tweaked public key that is used to associate assets
	// together across distinct asset IDs, allowing further issuance of the
	// asset to be made possible. The tweaked public key is the result of:
	//
	// 	internalKey = rawKey + singleTweak * G
	// 	tweakedGroupKey = TapTweak(internalKey, tapTweak)
	GroupPubKey btcec.PublicKey

	// TapscriptRoot represents the root of the Tapscript tree that commits
	// to all script spend conditions associated with the group key. Instead
	// of simply authorizing asset spending, these scripts enable more
	// complex witness mechanisms beyond a Schnorr signature, allowing for
	// reissuance of assets. A group key with an empty Tapscript root can
	// only authorize reissuance using a signature.
	//
	// In the V1 group key construction, this root is never empty. It always
	// includes two layers of script leaves that commit to the group
	// anchor's (genesis) asset ID, ensuring any user-provided Tapscript
	// root is positioned at level 2.
	TapscriptRoot []byte

	// CustomTapscriptRoot is an optional tapscript root to graft at the
	// second level of the tapscript tree, if specified.
	CustomTapscriptRoot fn.Option[chainhash.Hash]

	// Witness is a stack of witness elements that authorizes the membership
	// of an asset in a particular asset group. The witness can be a single
	// signature or a script from the tapscript tree committed to with the
	// TapscriptRoot, and follows the witness rules in BIP-341.
	Witness wire.TxWitness
}

GroupKey is the tweaked public key that is used to associate assets together across distinct asset IDs, allowing further issuance of the asset to be made possible.

func AssembleGroupKeyFromWitness added in v0.4.0

func AssembleGroupKeyFromWitness(genTx GroupVirtualTx, req GroupKeyRequest,
	tapLeaf *psbt.TaprootTapLeafScript, scriptWitness []byte) (*GroupKey,
	error)

AssembleGroupKeyFromWitness constructs a group key given a group witness generated externally.

func DeriveGroupKey

func DeriveGroupKey(genSigner GenesisSigner, genTx GroupVirtualTx,
	req GroupKeyRequest, tapLeaf *psbt.TaprootTapLeafScript) (*GroupKey,
	error)

DeriveGroupKey derives an asset's group key based on an internal public key descriptor, the original group asset genesis, and the asset's genesis.

func RandGroupKey

func RandGroupKey(t rapid.TB, genesis Genesis, newAsset *Asset) *GroupKey

RandGroupKey creates a random group key for testing.

func RandGroupKeyWithSigner

func RandGroupKeyWithSigner(t rapid.TB, privKey *btcec.PrivateKey,
	genesis Genesis, newAsset *Asset) (*GroupKey, []byte)

RandGroupKeyWithSigner creates a random group key for testing, and provides the signer for reissuing assets into the same group.

func (*GroupKey) IsEqual

func (g *GroupKey) IsEqual(otherGroupKey *GroupKey) bool

IsEqual returns true if this group key and signature are exactly equivalent to the passed other group key.

func (*GroupKey) IsEqualGroup

func (g *GroupKey) IsEqualGroup(otherGroupKey *GroupKey) bool

IsEqualGroup returns true if this group key describes the same asset group as the passed other group key.

func (*GroupKey) IsLocal

func (g *GroupKey) IsLocal() bool

IsLocal returns true if the private key that corresponds to this group key is held by this daemon. A non-local group key is stored with the internal key family and index set to their default values, 0.

type GroupKeyRequest added in v0.4.0

type GroupKeyRequest struct {
	// Version is the version of the group key construction.
	Version GroupKeyVersion

	// RawKey is the raw group key before the tweak with the genesis point
	// has been applied.
	RawKey keychain.KeyDescriptor

	// ExternalKey specifies a public key that, when provided, is used to
	// externally sign the group virtual transaction outside of tapd.
	//
	// If this field is set, RawKey is not used.
	ExternalKey fn.Option[ExternalKey]

	// AnchorGen is the genesis of the group anchor, which is the asset used
	// to derive the single tweak for the group key. For a new group key,
	// this will be the genesis of the new asset.
	AnchorGen Genesis

	// TapscriptRoot is the root of a Tapscript tree that includes script
	// spend conditions for the group key. A group key with an empty
	// Tapscript root can only authorize re-issuance with a signature. This
	// is the root of any user-defined scripts. For a V1 group key
	// construction the final tapscript root will never be empty.
	TapscriptRoot []byte

	// CustomTapscriptRoot is an optional tapscript root to graft at the
	// second level of the tapscript tree, if specified.
	CustomTapscriptRoot fn.Option[chainhash.Hash]

	// NewAsset is the asset which we are requesting group membership for.
	// A successful request will produce a witness that authorizes this
	// asset to be a member of this asset group.
	NewAsset *Asset
}

GroupKeyRequest contains the essential fields used to derive a group key.

func NewGroupKeyRequest added in v0.4.0

func NewGroupKeyRequest(internalKey keychain.KeyDescriptor,
	externalKey fn.Option[ExternalKey], anchorGen Genesis,
	newAsset *Asset, tapscriptRoot []byte,
	customTapscriptRoot fn.Option[chainhash.Hash]) (*GroupKeyRequest,
	error)

NewGroupKeyRequest constructs and validates a group key request.

func NewGroupKeyRequestNoErr added in v0.4.0

func NewGroupKeyRequestNoErr(t testing.TB, internalKey keychain.KeyDescriptor,
	externalKey fn.Option[ExternalKey], gen Genesis, newAsset *Asset,
	scriptRoot []byte,
	customTapscriptRoot fn.Option[chainhash.Hash]) *GroupKeyRequest

func (*GroupKeyRequest) BuildGroupVirtualTx added in v0.4.0

func (req *GroupKeyRequest) BuildGroupVirtualTx(genBuilder GenesisTxBuilder) (
	*GroupVirtualTx, error)

BuildGroupVirtualTx derives the tweaked group key for group key request, and constructs the group virtual TX needed to construct a sign descriptor and produce an asset group witness.

func (*GroupKeyRequest) NewGroupPubKey added in v0.5.1

func (req *GroupKeyRequest) NewGroupPubKey(genesisAssetID ID) (btcec.PublicKey,
	error)

NewGroupPubKey derives a group key for the asset group based on the group key request and the genesis asset ID.

func (*GroupKeyRequest) Validate added in v0.4.0

func (req *GroupKeyRequest) Validate() error

Validate ensures that the asset intended to be a member of an asset group is well-formed.

type GroupKeyReveal added in v0.3.0

type GroupKeyReveal interface {
	// Encode encodes the group key reveal into a writer.
	Encode(w io.Writer) error

	// Decode decodes the group key reveal from a reader.
	Decode(r io.Reader, buf *[8]byte, l uint64) error

	// RawKey returns the raw key of the group key reveal.
	RawKey() SerializedKey

	// SetRawKey sets the raw key of the group key reveal.
	SetRawKey(SerializedKey)

	// TapscriptRoot returns the tapscript root of the group key reveal.
	TapscriptRoot() []byte

	// SetTapscriptRoot sets the tapscript root of the group key reveal.
	SetTapscriptRoot([]byte)

	// GroupPubKey returns the group public key derived from the group key
	// reveal.
	GroupPubKey(assetID ID) (*btcec.PublicKey, error)
}

GroupKeyReveal represents the data used to derive the adjusted key that uniquely identifies an asset group.

func NewGroupKeyReveal added in v0.5.1

func NewGroupKeyReveal(groupKey GroupKey, genesisAssetID ID) (GroupKeyReveal,
	error)

NewGroupKeyReveal creates a new group key reveal instance from the given group key and genesis asset ID.

func NewGroupKeyRevealV0 added in v0.5.0

func NewGroupKeyRevealV0(rawKey SerializedKey,
	tapscriptRoot []byte) GroupKeyReveal

NewGroupKeyRevealV0 creates a new version 0 group key reveal instance.

type GroupKeyRevealTapscript added in v0.5.0

type GroupKeyRevealTapscript struct {
	// contains filtered or unexported fields
}

GroupKeyRevealTapscript holds data used to derive the tapscript root, which is then used to calculate the asset group key.

More broadly, the asset group key is the Taproot output key, derived using the standard formula:

outputKey = internalKey + TapTweak(internalKey || tapscriptRoot) * G

This formula demonstrates that the asset group key (Taproot output key) commits to both the internal key and the tapscript tree root hash.

By design, the tapscript root commits to a single genesis asset ID, which ensures that the asset group key also commits to the same unique genesis asset ID. This prevents asset group keys from being reused across different genesis assets or non-compliant asset minting tranches (e.g., tranches of a different asset type).

The tapscript tree is formulated to guarantee that only one recognizable genesis asset ID can exist in the tree. The ID is uniquely placed in the first leaf layer, which contains exactly two nodes: the ID leaf and its sibling (if present). The sibling node is deliberately constructed to ensure it cannot be mistaken for a genesis asset ID leaf.

The sibling node, `[tweaked_custom_branch]`, of the genesis asset ID leaf is a branch node by design and is only required if the user wants to use custom scripts. It serves two purposes:

  1. It ensures that only one genesis asset ID leaf can exist in the first layer, as it is not a valid genesis asset ID leaf.
  2. It optionally supports user-defined script spending leaves, enabling flexibility for custom tapscript subtrees.

User-defined script spending leaves are nested under `[tweaked_custom_branch]` as a single node hash, `custom_root_hash`. This hash may represent either a single leaf or the root hash of an entire subtree.

A sibling node is included alongside the `custom_root_hash` node. This sibling is a non-spendable script leaf containing `non_spend()`. Its presence ensures that one of the two positions in the first layer of the tapscript tree is occupied by a branch node. Due to the pre-image resistance of SHA-256, this prevents the existence of a second recognizable genesis asset ID leaf.

The final tapscript tree adopts the following structure:

                       [tapscript_root]
                         /          \
[non_spend(<genesis asset ID>)]   [tweaked_custom_branch]
                                      /        \
                              [non_spend()]   <custom_root_hash>

Where:

  • [tapscript_root] is the root of the final tapscript tree.
  • [non_spend(<genesis asset ID>)] is a first-layer non-spendable script leaf that commits to the genesis asset ID.
  • [tweaked_custom_branch] is a branch node that serves two purposes: 1. It cannot be misinterpreted as a genesis asset ID leaf. 2. It optionally includes user-defined script spending leaves.
  • <custom_root_hash> is the root hash of the custom tapscript subtree. If not specified, the whole right branch [tweaked_custom_branch] is omitted (see below).
  • non_spend(data) is a non-spendable script leaf that contains the data argument. The data can be nil/empty in which case, the un-spendable script doesn't commit to the data. Its presence ensures that [tweaked_custom_branch] remains a branch node and cannot be a valid genesis asset ID leaf. Two non-spendable script leaves are possible:
  • One that uses an OP_RETURN to create a script that will "return early" and terminate the script execution.
  • One that uses a normal OP_CHECKSIG operator where the pubkey argument is a key that cannot be signed with. We generate this special public key using a Pedersen commitment, where the message is the asset ID (or 32 all-zero bytes in case data is nil/empty). To achieve hardware wallet support, that key is then turned into an extended key (xpub) and a child key at path 0/0 is used as the actual public key that goes into the OP_CHECKSIG script.

If `custom_root_hash` is not provided, then there is no sibling to the asset ID leaf, meaning the tree only has a single leaf. This makes it possible to turn the single asset ID leaf into a miniscript policy, either using raw(hex(OP_RETURN <asset_id>)) or pk(<Pedersen commitment key>). The final tapscript tree with no custom scripts adopts the following structure:

      [tapscript_root]
             |
[non_spend(<genesis asset ID>)]

Where:

  • [tapscript_root] is the root of the final tapscript tree.
  • [non_spend(<genesis asset ID>)] is a first-layer non-spendable script leaf that commits to the genesis asset ID.
  • non_spend(data) is a non-spendable script leaf that contains the data argument. The data can be nil/empty in which case, the un-spendable script doesn't commit to the data. Its presence ensures that [tweaked_custom_branch] remains a branch node and cannot be a valid genesis asset ID leaf. Two non-spendable script leaves are possible:
  • One that uses an OP_RETURN to create a script that will "return early" and terminate the script execution.
  • One that uses a normal OP_CHECKSIG operator where the pubkey argument is a key that cannot be signed with. We generate this special public key using a Pedersen commitment, where the message is the asset ID (or 32 all-zero bytes in case data is nil/empty). To achieve hardware wallet support, that key is then turned into an extended key (xpub) and a child key at path 0/0 is used as the actual public key that goes into the OP_CHECKSIG script.

func NewGroupKeyTapscriptRoot added in v0.5.0

func NewGroupKeyTapscriptRoot(version NonSpendLeafVersion, genesisAssetID ID,
	customRoot fn.Option[chainhash.Hash]) (GroupKeyRevealTapscript, []byte,
	error)

NewGroupKeyTapscriptRoot computes the final tapscript root hash which is used to derive the asset group key. The final tapscript root hash is computed from the genesis asset ID and an optional custom tapscript subtree root hash.

func (*GroupKeyRevealTapscript) Root added in v0.5.1

Root returns the final tapscript root hash of the group key reveal tapscript.

func (*GroupKeyRevealTapscript) Validate added in v0.5.0

func (g *GroupKeyRevealTapscript) Validate(assetID ID) error

Validate checks that the group key reveal tapscript is well-formed and compliant.

type GroupKeyRevealTlvType added in v0.5.0

type GroupKeyRevealTlvType = tlv.Type

GroupKeyRevealTlvType represents the different TLV types for GroupKeyReveal TLV records.

const (
	GKRVersion           GroupKeyRevealTlvType = 0
	GKRInternalKey       GroupKeyRevealTlvType = 2
	GKRTapscriptRoot     GroupKeyRevealTlvType = 4
	GKRCustomSubtreeRoot GroupKeyRevealTlvType = 7
)

type GroupKeyRevealV0 added in v0.5.0

type GroupKeyRevealV0 struct {
	// contains filtered or unexported fields
}

GroupKeyRevealV0 is a version 0 group key reveal type for representing the data used to derive the tweaked key used to identify an asset group. The final tweaked key is the result of: TapTweak(groupInternalKey, tapscriptRoot)

func (*GroupKeyRevealV0) Decode added in v0.5.0

func (g *GroupKeyRevealV0) Decode(r io.Reader, buf *[8]byte, l uint64) error

Decode decodes the group key reveal from the reader.

func (*GroupKeyRevealV0) Encode added in v0.5.0

func (g *GroupKeyRevealV0) Encode(w io.Writer) error

Encode encodes the group key reveal into the writer.

func (*GroupKeyRevealV0) GroupPubKey added in v0.5.0

func (g *GroupKeyRevealV0) GroupPubKey(assetID ID) (*btcec.PublicKey, error)

GroupPubKey returns the group public key derived from the group key reveal.

func (*GroupKeyRevealV0) RawKey added in v0.5.0

func (g *GroupKeyRevealV0) RawKey() SerializedKey

RawKey returns the raw key of the group key reveal.

func (*GroupKeyRevealV0) SetRawKey added in v0.5.0

func (g *GroupKeyRevealV0) SetRawKey(rawKey SerializedKey)

SetRawKey sets the raw key of the group key reveal.

func (*GroupKeyRevealV0) SetTapscriptRoot added in v0.5.0

func (g *GroupKeyRevealV0) SetTapscriptRoot(tapscriptRoot []byte)

SetTapscriptRoot sets the tapscript root of the group key reveal.

func (*GroupKeyRevealV0) TapscriptRoot added in v0.5.0

func (g *GroupKeyRevealV0) TapscriptRoot() []byte

TapscriptRoot returns the tapscript root of the group key reveal.

type GroupKeyRevealV1 added in v0.5.0

type GroupKeyRevealV1 struct {
	// contains filtered or unexported fields
}

GroupKeyRevealV1 is a version 1 group key reveal type for representing the data used to derive and verify the tweaked key used to identify an asset group.

func NewGroupKeyRevealV1 added in v0.5.0

func NewGroupKeyRevealV1(version NonSpendLeafVersion,
	internalKey btcec.PublicKey, genesisAssetID ID,
	customRoot fn.Option[chainhash.Hash]) (GroupKeyRevealV1, error)

NewGroupKeyRevealV1 creates a new version 1 group key reveal instance.

func (*GroupKeyRevealV1) CustomSubtreeRoot added in v0.5.0

func (g *GroupKeyRevealV1) CustomSubtreeRoot() fn.Option[chainhash.Hash]

CustomSubtreeRoot returns the custom subtree root hash of the group key reveal.

func (*GroupKeyRevealV1) Decode added in v0.5.0

func (g *GroupKeyRevealV1) Decode(r io.Reader, buf *[8]byte, l uint64) error

Decode decodes the group key reveal from a reader.

func (*GroupKeyRevealV1) Encode added in v0.5.0

func (g *GroupKeyRevealV1) Encode(w io.Writer) error

Encode encodes the group key reveal into a writer.

This encoding routine must ensure the resulting serialized bytes are sufficiently long to prevent the decoding routine from mistakenly using the wrong group key reveal version. Specifically, the raw key, tapscript root, and version fields must be properly populated.

func (*GroupKeyRevealV1) GroupPubKey added in v0.5.0

func (g *GroupKeyRevealV1) GroupPubKey(assetID ID) (*btcec.PublicKey, error)

GroupPubKey returns the group public key derived from the group key reveal.

func (*GroupKeyRevealV1) RawKey added in v0.5.0

func (g *GroupKeyRevealV1) RawKey() SerializedKey

RawKey returns the raw key of the group key reveal.

func (*GroupKeyRevealV1) ScriptSpendControlBlock added in v0.5.0

func (g *GroupKeyRevealV1) ScriptSpendControlBlock(
	genesisAssetID ID) (txscript.ControlBlock, error)

ScriptSpendControlBlock returns the control block for the script spending path in the custom tapscript subtree.

func (*GroupKeyRevealV1) SetRawKey added in v0.5.0

func (g *GroupKeyRevealV1) SetRawKey(rawKey SerializedKey)

SetRawKey sets the raw key of the group key reveal.

func (*GroupKeyRevealV1) SetTapscriptRoot added in v0.5.0

func (g *GroupKeyRevealV1) SetTapscriptRoot(tapscriptRootBytes []byte)

SetTapscriptRoot sets the tapscript root of the group key reveal.

func (*GroupKeyRevealV1) TapscriptRoot added in v0.5.0

func (g *GroupKeyRevealV1) TapscriptRoot() []byte

TapscriptRoot returns the tapscript root of the group key reveal.

func (*GroupKeyRevealV1) Version added in v0.5.1

Version returns the commitment version of the group key reveal V1.

type GroupKeyVersion added in v0.5.1

type GroupKeyVersion uint8

GroupKeyVersion denotes the version of the group key construction.

const (
	// GroupKeyV0 is the initial version of the group key where the group
	// internal key is tweaked with the group anchor's asset ID.
	GroupKeyV0 GroupKeyVersion = 0

	// GroupKeyV1 is the version of the group key that uses a construction
	// that is compatible with PSBT signing where the group anchor's asset
	// ID is appended as a sibling to any user-provided tapscript tree.
	GroupKeyV1 GroupKeyVersion = 1
)

func NewGroupKeyVersion added in v0.5.1

func NewGroupKeyVersion(v int32) (GroupKeyVersion, error)

NewGroupKeyVersion creates a new GroupKeyVersion from an int32. This function is useful for decoding GroupKeyVersions from the SQL database.

type GroupVirtualTx added in v0.4.0

type GroupVirtualTx struct {
	// Tx is a virtual transaction that represents the genesis state
	// transition of a grouped asset.
	Tx wire.MsgTx

	// PrevOut is a transaction output that represents a grouped asset.
	// PrevOut uses the tweaked group key as its PkScript. This is used in
	// combination with GroupVirtualTx.Tx as input for a GenesisSigner.
	PrevOut wire.TxOut

	// GenID is the asset ID of the grouped asset in a GroupKeyRequest. This
	// ID is needed to construct a sign descriptor for a GenesisSigner, as
	// it is the single tweak for the group internal key.
	GenID ID

	// TweakedKey is the tweaked group key for the given GroupKeyRequest.
	// This is later used to construct a complete GroupKey, after a
	// GenesisSigner has produced an asset group witness.
	TweakedKey btcec.PublicKey
}

GroupVirtualTx contains all the information needed to produce an asset group witness, except for the group internal key descriptor (or private key). A GroupVirtualTx is constructed from a GroupKeyRequest.

type ID

type ID [sha256.Size]byte

ID serves as a unique identifier of an asset, resulting from:

sha256(genesisOutPoint || sha256(tag) || sha256(metadata) ||
  outputIndex || assetType)

func RandID

func RandID(t testing.TB) ID

RandID creates a random asset ID.

func (*ID) Record added in v0.4.0

func (i *ID) Record() tlv.Record

Record returns a TLV record that can be used to encode/decode an ID to/from a TLV stream.

NOTE: This is part of the tlv.RecordProducer interface.

func (ID) String

func (i ID) String() string

String returns the hex-encoded string representation of the ID.

type LeafKeySet added in v0.5.0

type LeafKeySet = fn.Set[[32]byte]

LeafKeySet is a set of leaf keys.

func NewLeafKeySet added in v0.5.0

func NewLeafKeySet() LeafKeySet

NewLeafKeySet creates a new leaf key set.

type LeafTlvType

type LeafTlvType = tlv.Type

LeafTlvType represents the different TLV types for Asset Leaf TLV records.

const (
	LeafVersion             LeafTlvType = 0
	LeafGenesis             LeafTlvType = 2
	LeafType                LeafTlvType = 4
	LeafAmount              LeafTlvType = 6
	LeafLockTime            LeafTlvType = 7
	LeafRelativeLockTime    LeafTlvType = 9
	LeafPrevWitness         LeafTlvType = 11
	LeafSplitCommitmentRoot LeafTlvType = 13
	LeafScriptVersion       LeafTlvType = 14
	LeafScriptKey           LeafTlvType = 16
	LeafGroupKey            LeafTlvType = 17
)

type MockGenesisSigner added in v0.3.0

type MockGenesisSigner struct {
	// contains filtered or unexported fields
}

MockGenesisSigner implements the GenesisSigner interface using a raw private key.

func NewMockGenesisSigner added in v0.3.0

func NewMockGenesisSigner(priv *btcec.PrivateKey) *MockGenesisSigner

NewMockGenesisSigner creates a new MockGenesisSigner instance given the passed public key.

func (*MockGenesisSigner) SignVirtualTx added in v0.3.0

func (r *MockGenesisSigner) SignVirtualTx(signDesc *lndclient.SignDescriptor,
	virtualTx *wire.MsgTx, prevOut *wire.TxOut) (*schnorr.Signature,
	error)

SignVirtualTx generates a signature according to the passed signing descriptor and virtual TX.

type MockGroupTxBuilder added in v0.3.0

type MockGroupTxBuilder struct{}

func (*MockGroupTxBuilder) BuildGenesisTx added in v0.3.0

func (m *MockGroupTxBuilder) BuildGenesisTx(newAsset *Asset) (*wire.MsgTx,
	*wire.TxOut, error)

BuildGenesisTx constructs a virtual transaction and prevOut that represent the genesis state transition for a grouped asset. This output is used to create a group witness for the grouped asset.

type NewAssetOpt added in v0.3.0

type NewAssetOpt func(*newAssetOptions)

NewAssetOpt is used to modify how a new asset is to be created.

func WithAssetVersion added in v0.3.0

func WithAssetVersion(v Version) NewAssetOpt

WithAssetVersion can be used to create an asset with a custom version.

type NonSpendLeafVersion added in v0.5.1

type NonSpendLeafVersion = uint8

NonSpendLeafVersion is the version of the group key reveal.

Version 1 is the original version that's based on an OP_RETURN.

Version 2 is a follow-up version that instead uses a Pedersen commitment.

const (
	// OpReturnVersion is the version of the group key reveal that uses an
	// OP_RETURN.
	OpReturnVersion NonSpendLeafVersion = 1

	// PedersenVersion is the version of the group key reveal that uses a
	// Pedersen commitment.
	PedersenVersion NonSpendLeafVersion = 2
)

type PendingGroupWitness added in v0.4.0

type PendingGroupWitness struct {
	GenID   ID
	Witness wire.TxWitness
}

PendingGroupWitness specifies the asset group witness for an asset seedling in an unsealed minting batch.

type PrevID

type PrevID struct {
	// OutPoint refers to the asset's previous output position within a
	// transaction.
	OutPoint wire.OutPoint

	// ID is the asset ID of the previous asset tree.
	ID ID

	// ScriptKey is the previously tweaked Taproot output key committing to
	// the possible spending conditions of the asset. PrevID is being used
	// as map keys, so we want to only use data types with fixed and
	// comparable content, which a btcec.PublicKey might not be.
	ScriptKey SerializedKey
}

PrevID serves as a reference to an asset's previous input.

func (PrevID) Hash

func (id PrevID) Hash() [sha256.Size]byte

Hash returns the SHA-256 hash of all items encapsulated by PrevID.

type ScriptKey

type ScriptKey struct {
	// PubKey is the script key that'll be encoded in the final TLV format.
	// All signatures are checked against this script key.
	PubKey *btcec.PublicKey

	*TweakedScriptKey
}

ScriptKey represents a tweaked Taproot output key encumbering the different ways an asset can be spent.

func GenChallengeNUMS added in v0.5.0

func GenChallengeNUMS(challengeBytesOpt fn.Option[[32]byte]) ScriptKey

GenChallengeNUMS generates a variant of the NUMS script key that is modified by the provided challenge.

The resulting scriptkey is:
res := NUMS + challenge*G

func NewScriptKey

func NewScriptKey(key *btcec.PublicKey) ScriptKey

NewScriptKey constructs a ScriptKey with only the publicly available information. This resulting key may or may not have a tweak applied to it.

func NewScriptKeyBip86

func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey

NewScriptKeyBip86 constructs a ScriptKey tweaked BIP-0086 style. The resulting script key will include the specified BIP-0086 tweak (no real tweak), and also apply that to the final external PubKey.

func RandScriptKey

func RandScriptKey(t testing.TB) ScriptKey

RandScriptKey creates a random script key for testing.

func (*ScriptKey) DeclaredAsKnown added in v0.4.0

func (s *ScriptKey) DeclaredAsKnown() bool

DeclaredAsKnown returns true if this script key has either been derived by the local wallet or was explicitly declared to be known by using the DeclareScriptKey RPC. Knowing the key conceptually means the key belongs to the local wallet or is at least known by a software that operates on the local wallet. The DeclaredAsKnown flag is never serialized in proofs, so this is never explicitly set for keys foreign to the local wallet. Therefore, if this method returns true for a script key, it means the asset with the script key will be shown in the wallet balance.

func (*ScriptKey) HasScriptPath added in v0.4.0

func (s *ScriptKey) HasScriptPath() bool

HasScriptPath returns true if we know the internals of the script key and there is a tweak applied to it. This means that the script key is not a BIP-0086 key.

func (*ScriptKey) IsEqual added in v0.4.0

func (s *ScriptKey) IsEqual(otherScriptKey *ScriptKey) bool

IsEqual returns true is this script key is exactly equivalent to the passed other script key.

func (*ScriptKey) IsUnSpendable

func (s *ScriptKey) IsUnSpendable() (bool, error)

IsUnSpendable returns true if this script key is equal to the un-spendable NUMS point.

type ScriptVersion

type ScriptVersion uint16

ScriptVersion denotes the asset script versioning scheme.

const (
	// ScriptV0 represents the initial asset script version of the Taproot
	// Asset protocol. In this version, assets commit to a tweaked Taproot
	// output key, allowing the ability for an asset to indirectly commit to
	// multiple spending conditions.
	ScriptV0 ScriptVersion = 0
)

type SerializedKey

type SerializedKey [33]byte

SerializedKey is a type for representing a public key, serialized in the compressed, 33-byte form.

func RandSerializedKey

func RandSerializedKey(t testing.TB) SerializedKey

RandSerializedKey creates a random serialized key for testing.

func ToSerialized

func ToSerialized(pubKey *btcec.PublicKey) SerializedKey

ToSerialized serializes a public key in its 33-byte compressed form.

func (SerializedKey) CopyBytes

func (s SerializedKey) CopyBytes() []byte

CopyBytes returns a copy of the underlying array as a byte slice.

func (SerializedKey) SchnorrSerialized

func (s SerializedKey) SchnorrSerialized() []byte

SchnorrSerialized returns the Schnorr serialized, x-only 32-byte representation of the serialized key.

func (SerializedKey) ToPubKey added in v0.3.0

func (s SerializedKey) ToPubKey() (*btcec.PublicKey, error)

ToPubKey returns the public key parsed from the serialized key.

type Specifier added in v0.4.0

type Specifier struct {
	// contains filtered or unexported fields
}

Specifier is a type that can be used to specify an asset by its ID, its asset group public key, or both.

func NewSpecifier added in v0.5.0

func NewSpecifier(id *ID, groupPubKey *btcec.PublicKey, groupKey *GroupKey,
	mustBeSpecified bool) (Specifier, error)

NewSpecifier creates a new Specifier instance based on the provided parameters.

The Specifier identifies an asset using either an asset ID, a group public key, or a group key. At least one of these must be specified if the `mustBeSpecified` parameter is set to true.

func NewSpecifierFromGroupKey added in v0.4.0

func NewSpecifierFromGroupKey(groupPubKey btcec.PublicKey) Specifier

NewSpecifierFromGroupKey creates a new specifier that specifies an asset by its group public key.

func NewSpecifierFromId added in v0.4.0

func NewSpecifierFromId(id ID) Specifier

NewSpecifierFromId creates a new specifier that specifies an asset by its ID.

func NewSpecifierOptionalGroupKey added in v0.4.0

func NewSpecifierOptionalGroupKey(id ID, groupKey *GroupKey) Specifier

NewSpecifierOptionalGroupKey creates a new specifier that specifies an asset by its ID and an optional group key.

func NewSpecifierOptionalGroupPubKey added in v0.4.0

func NewSpecifierOptionalGroupPubKey(id ID,
	groupPubKey *btcec.PublicKey) Specifier

NewSpecifierOptionalGroupPubKey creates a new specifier that specifies an asset by its ID and an optional group public key.

func (*Specifier) AsBytes added in v0.4.0

func (s *Specifier) AsBytes() ([]byte, []byte)

AsBytes returns the asset ID and group public key as byte slices.

func (*Specifier) HasGroupPubKey added in v0.4.0

func (s *Specifier) HasGroupPubKey() bool

HasGroupPubKey returns true if the asset group public key field is specified.

func (*Specifier) HasId added in v0.4.0

func (s *Specifier) HasId() bool

HasId returns true if the asset ID field is specified.

func (*Specifier) ID added in v0.5.1

func (s *Specifier) ID() fn.Option[ID]

ID returns the underlying asset ID option of the specifier.

func (*Specifier) IsSome added in v0.5.0

func (s *Specifier) IsSome() bool

IsSome returns true if the specifier is set.

func (*Specifier) String added in v0.5.0

func (s *Specifier) String() string

String returns a human-readable description of the specifier.

func (*Specifier) UnwrapGroupKeyToPtr added in v0.4.0

func (s *Specifier) UnwrapGroupKeyToPtr() *btcec.PublicKey

UnwrapGroupKeyToPtr unwraps the asset group public key field to a pointer.

func (*Specifier) UnwrapIdOrErr added in v0.4.0

func (s *Specifier) UnwrapIdOrErr() (ID, error)

UnwrapIdOrErr unwraps the ID field or returns an error if it is not specified.

func (*Specifier) UnwrapIdToPtr added in v0.4.0

func (s *Specifier) UnwrapIdToPtr() *ID

UnwrapIdToPtr unwraps the ID field to a pointer.

func (*Specifier) UnwrapToPtr added in v0.5.0

func (s *Specifier) UnwrapToPtr() (*ID, *btcec.PublicKey)

UnwrapToPtr unwraps the asset ID and asset group public key fields, returning them as pointers.

func (*Specifier) WhenGroupPubKey added in v0.4.0

func (s *Specifier) WhenGroupPubKey(f func(btcec.PublicKey))

WhenGroupPubKey executes the given function if asset group public key field is specified.

func (*Specifier) WhenId added in v0.4.0

func (s *Specifier) WhenId(f func(ID))

WhenId executes the given function if the ID field is specified.

type SplitCommitment

type SplitCommitment struct {
	// Proof is the proof for a particular asset split resulting from a
	// split commitment.
	Proof mssmt.Proof

	// RootAsset is the asset containing the root of the split commitment
	// tree from which the `Proof` above was computed from.
	RootAsset Asset
}

SplitCommitment represents the asset witness for an asset split.

func (*SplitCommitment) DeepEqual

func (s *SplitCommitment) DeepEqual(o *SplitCommitment) bool

DeepEqual returns true if this split commitment is equal with the given split commitment.

type TapBranchNodes added in v0.4.0

type TapBranchNodes struct {
	// contains filtered or unexported fields
}

TapBranchNodes represents the tapHashes of the child nodes of a TapBranch. These tapHashes can be stored to and loaded from the DB.

func DecodeTapBranchNodes added in v0.4.0

func DecodeTapBranchNodes(branchData [][]byte) (*TapBranchNodes, error)

type TapLeafNodes added in v0.4.0

type TapLeafNodes struct {
	// contains filtered or unexported fields
}

TapLeafNodes represents an ordered list of TapLeaf objects, that have been checked for their script version and size. These leaves can be stored to and loaded from the DB.

func DecodeTapLeafNodes added in v0.4.0

func DecodeTapLeafNodes(leafData [][]byte) (*TapLeafNodes, error)

type TapscriptTreeManager added in v0.4.0

type TapscriptTreeManager interface {
	// StoreTapscriptTree persists a Tapscript tree given a validated set of
	// TapLeafs or a TapBranch. If the store succeeds, the root hash of the
	// Tapscript tree is returned.
	StoreTapscriptTree(ctx context.Context,
		treeNodes TapscriptTreeNodes) (*chainhash.Hash, error)

	// LoadTapscriptTree loads the Tapscript tree with the given root hash,
	// and decodes the tree into a TapscriptTreeNodes object.
	LoadTapscriptTree(ctx context.Context,
		rootHash chainhash.Hash) (*TapscriptTreeNodes, error)

	// DeleteTapscriptTree deletes the Tapscript tree with the given root
	// hash.
	DeleteTapscriptTree(ctx context.Context, rootHash chainhash.Hash) error
}

TapscriptTreeManager is used to persist a Tapscript tree, represented as either a slice of TapLeafs or a TapBranch. After a tree is stored, it can be referenced by its root hash. This root hash can be stored as a tweak for keys such as a batch internal key, group key, or asset script key.

type TapscriptTreeNodes added in v0.4.0

type TapscriptTreeNodes struct {
	// contains filtered or unexported fields
}

TapscriptTreeNodes represents the two supported ways to define a tapscript tree to be used as a sibling for a Taproot Asset commitment, an asset group key, or an asset script key. This type is used for interfacing with the DB, not for supplying in a proof or key derivation. The inner fields are mutually exclusive.

func FromBranch added in v0.4.0

func FromBranch(tbn TapBranchNodes) TapscriptTreeNodes

FromBranch creates a TapscriptTreeNodes object from a TapBranchNodes object.

func FromLeaves added in v0.4.0

func FromLeaves(tln TapLeafNodes) TapscriptTreeNodes

FromLeaves creates a TapscriptTreeNodes object from a TapLeafNodes object.

func TapTreeNodesFromBranch added in v0.4.0

func TapTreeNodesFromBranch(branch txscript.TapBranch) TapscriptTreeNodes

TapTreeNodesFromBranch creates a TapscriptTreeNodes object from a TapBranch.

func TapTreeNodesFromLeaves added in v0.4.0

func TapTreeNodesFromLeaves(leaves []txscript.TapLeaf) (*TapscriptTreeNodes,
	error)

TapTreeNodesFromLeaves sanity checks an ordered list of TapLeaf objects and constructs a TapscriptTreeNodes object if all leaves are valid.

type TestAsset added in v0.3.0

type TestAsset struct {
	Version             uint8           `json:"version"`
	GenesisFirstPrevOut string          `json:"genesis_first_prev_out"`
	GenesisTag          string          `json:"genesis_tag"`
	GenesisMetaHash     string          `json:"genesis_meta_hash"`
	GenesisOutputIndex  uint32          `json:"genesis_output_index"`
	GenesisType         uint8           `json:"genesis_type"`
	Amount              uint64          `json:"amount"`
	LockTime            uint64          `json:"lock_time"`
	RelativeLockTime    uint64          `json:"relative_lock_time"`
	PrevWitnesses       []*TestWitness  `json:"prev_witnesses"`
	SplitCommitmentRoot *mssmt.TestNode `json:"split_commitment_root"`
	ScriptVersion       uint16          `json:"script_version"`
	ScriptKey           string          `json:"script_key"`
	GroupKey            *TestGroupKey   `json:"group_key"`
	UnknownOddTypes     tlv.TypeMap     `json:"unknown_odd_types"`
}

func NewTestFromAsset added in v0.3.0

func NewTestFromAsset(t testing.TB, a *Asset) *TestAsset

func (*TestAsset) ToAsset added in v0.3.0

func (ta *TestAsset) ToAsset(t testing.TB) *Asset

type TestGenesisReveal added in v0.3.0

type TestGenesisReveal struct {
	FirstPrevOut string `json:"first_prev_out"`
	Tag          string `json:"tag"`
	MetaHash     string `json:"meta_hash"`
	OutputIndex  uint32 `json:"output_index"`
	Type         uint8  `json:"type"`
}

func NewTestFromGenesisReveal added in v0.3.0

func NewTestFromGenesisReveal(t testing.TB, g *Genesis) *TestGenesisReveal

func (*TestGenesisReveal) ToGenesisReveal added in v0.3.0

func (tgr *TestGenesisReveal) ToGenesisReveal(t testing.TB) *Genesis

type TestGroupKey added in v0.3.0

type TestGroupKey struct {
	GroupKey string `json:"group_key"`
}

func NewTestFromGroupKey added in v0.3.0

func NewTestFromGroupKey(t testing.TB, gk *GroupKey) *TestGroupKey

func (*TestGroupKey) ToGroupKey added in v0.3.0

func (tgk *TestGroupKey) ToGroupKey(t testing.TB) *GroupKey

type TestGroupKeyReveal added in v0.3.0

type TestGroupKeyReveal struct {
	RawKey        string `json:"raw_key"`
	TapscriptRoot string `json:"tapscript_root"`
}

func NewTestFromGroupKeyReveal added in v0.3.0

func NewTestFromGroupKeyReveal(t testing.TB,
	gkr GroupKeyReveal) *TestGroupKeyReveal

func (*TestGroupKeyReveal) ToGroupKeyReveal added in v0.3.0

func (tgkr *TestGroupKeyReveal) ToGroupKeyReveal(t testing.TB) GroupKeyReveal

type TestPrevID added in v0.3.0

type TestPrevID struct {
	OutPoint  string `json:"out_point"`
	AssetID   string `json:"asset_id"`
	ScriptKey string `json:"script_key"`
}

func NewTestFromPrevID added in v0.3.0

func NewTestFromPrevID(prevID *PrevID) *TestPrevID

func (*TestPrevID) ToPrevID added in v0.3.0

func (tpv *TestPrevID) ToPrevID(t testing.TB) *PrevID

type TestScriptKey added in v0.3.0

type TestScriptKey struct {
}

type TestSplitCommitment added in v0.3.0

type TestSplitCommitment struct {
	Proof     string     `json:"proof"`
	RootAsset *TestAsset `json:"root_asset"`
}

func NewTestFromSplitCommitment added in v0.3.0

func NewTestFromSplitCommitment(t testing.TB,
	sc *SplitCommitment) *TestSplitCommitment

func (*TestSplitCommitment) ToSplitCommitment added in v0.3.0

func (tsc *TestSplitCommitment) ToSplitCommitment(
	t testing.TB) *SplitCommitment

type TestVectors added in v0.3.0

type TestVectors struct {
	ValidTestCases []*ValidTestCase `json:"valid_test_cases"`
	ErrorTestCases []*ErrorTestCase `json:"error_test_cases"`
}

type TestWitness added in v0.3.0

type TestWitness struct {
	PrevID          *TestPrevID          `json:"prev_id"`
	TxWitness       []string             `json:"tx_witness"`
	SplitCommitment *TestSplitCommitment `json:"split_commitment"`
}

func NewTestFromWitness added in v0.3.0

func NewTestFromWitness(t testing.TB, w Witness) *TestWitness

func (*TestWitness) ToWitness added in v0.3.0

func (tw *TestWitness) ToWitness(t testing.TB) Witness

type TweakedScriptKey

type TweakedScriptKey struct {
	// RawKey is the raw script key before the script key tweak is applied.
	// We store a full key descriptor here for wallet purposes, but will
	// only encode the pubkey above for the normal script leaf TLV
	// encoding.
	RawKey keychain.KeyDescriptor

	// Tweak is the tweak that is applied on the raw script key to get the
	// public key. If this is nil, then a BIP-0086 tweak is assumed.
	Tweak []byte

	// DeclaredKnown indicates that this script key has been explicitly
	// declared as being important to the local wallet, even if it might not
	// be fully known to the local wallet. This could perhaps also be named
	// "imported", though that might imply that the corresponding private
	// key was also somehow imported and available. The only relevance this
	// flag has is that assets with a declared key are shown in the asset
	// list/balance.
	DeclaredKnown bool
}

TweakedScriptKey is an embedded struct which is primarily used by wallets to be able to keep track of the tweak of a script key alongside the raw key derivation information.

func (*TweakedScriptKey) IsEqual added in v0.4.0

func (ts *TweakedScriptKey) IsEqual(other *TweakedScriptKey) bool

IsEqual returns true is this tweaked script key is exactly equivalent to the passed other tweaked script key.

type Type

type Type uint8

Type denotes the asset types supported by the Taproot Asset protocol.

const (
	// Normal is an asset that can be represented in multiple units,
	// resembling a divisible asset.
	Normal Type = 0

	// Collectible is a unique asset, one that cannot be represented in
	// multiple units.
	Collectible Type = 1
)

func RandAssetType added in v0.4.0

func RandAssetType(t testing.TB) Type

RandAssetType creates a random asset type.

func (Type) String

func (t Type) String() string

String returns a human-readable description of the type.

type ValidBurnTestCase added in v0.3.0

type ValidBurnTestCase struct {
	PrevID   *TestPrevID `json:"prev_id"`
	Expected string      `json:"expected"`
	Comment  string      `json:"comment"`
}

type ValidTestCase added in v0.3.0

type ValidTestCase struct {
	Asset    *TestAsset `json:"asset"`
	Expected string     `json:"expected"`
	Comment  string     `json:"comment"`
}

type Version

type Version uint8

Version denotes the version of the Taproot Asset protocol in effect for an asset.

const (
	// V0 is the initial Taproot Asset protocol version.
	V0 Version = 0

	// V1 is the version of asset serialization that doesn't include the
	// witness field when creating a TAP commitment. This is similar to
	// segwit as found in Bitcoin land.
	V1 Version = 1
)

type Witness

type Witness struct {
	// PrevID is a reference to an asset's previous input.
	//
	// NOTE: This should only be nil upon the creation of an asset.
	PrevID *PrevID

	// TxWitness is a witness that satisfies the asset's previous ScriptKey.
	//
	// NOTE: This field and `SplitCommitmentProof` are mutually exclusive,
	// except upon the creation of an asset, where both should be nil.
	TxWitness wire.TxWitness

	// SplitCommitmentProof is used to permit the spending of an asset UTXO
	// created as a result of an asset split. When an asset is split, the
	// non-change UTXO commits to the location of all other splits within an
	// MS-SMT tree. When spending a change UTXO resulting from a
	// `SplitCommitment`, a normal `Witness` isn't required, instead the
	// owner of the change asset UTXO must prove that it holds a valid split
	// which was authorized by the main transfer transaction.
	//
	// Outputs with the same `SplitCommitment` are said to share a single
	// `Witness` as such outputs are the result of a new asset split.
	// Therefore, we only need a single witness and the resulting merkle-sum
	// asset tree to verify a transfer.
	//
	// NOTE: This field and `TxWitness` are mutually exclusive,
	// except upon the creation of an asset, where both should be nil.
	//
	// TODO: This still needs to be specified further in the BIPs, see
	// https://github.com/lightninglabs/taproot-assets/issues/3.
	SplitCommitment *SplitCommitment
}

Witness is a nested TLV stream within the main Asset TLV stream that contains the necessary data to verify the movement of an asset. All fields should be nil to represent the creation of an asset, `TxWitness` and `SplitCommitmentProof` are mutually exclusive otherwise.

func (*Witness) Decode

func (w *Witness) Decode(r io.Reader) error

Decode decodes an asset witness from a TLV stream.

func (*Witness) DecodeRecords

func (w *Witness) DecodeRecords() []tlv.Record

DecodeRecords provides all records known for an asset witness for proper decoding.

func (*Witness) DeepEqual

func (w *Witness) DeepEqual(skipTxWitness bool, o *Witness) bool

DeepEqual returns true if this witness is equal with the given witness. If the skipTxWitness boolean is set, the TxWitness field of the Witness is not compared.

func (*Witness) Encode

func (w *Witness) Encode(writer io.Writer) error

Encode encodes an asset witness into a TLV stream.

func (*Witness) EncodeNoWitness added in v0.3.0

func (w *Witness) EncodeNoWitness(writer io.Writer) error

EncodeNoWitness encodes an asset witness into a TLV stream, but does not include the raw witness field. The prevID and the split commitment are still included.

func (*Witness) EncodeRecords

func (w *Witness) EncodeRecords() []tlv.Record

EncodeRecords determines the non-nil records to include when encoding an asset witness at runtime.

type WitnessTlvType

type WitnessTlvType = tlv.Type

WitnessTlvType represents the different TLV types for Asset Witness TLV records.

const (
	WitnessPrevID          WitnessTlvType = 1
	WitnessTxWitness       WitnessTlvType = 3
	WitnessSplitCommitment WitnessTlvType = 5
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL