@@ -108,6 +108,50 @@ const (
108108 EncodeSegwit
109109)
110110
111+ // ScriptKeyType denotes the type of script key used for an asset. This type is
112+ // serialized to the database, so we don't use iota for the values to ensure
113+ // they don't change by accident.
114+ type ScriptKeyType uint8
115+
116+ const (
117+ // ScriptKeyUnknown is the default script key type used for assets that
118+ // we don't know the type of. This should only be stored for assets
119+ // where we don't know the internal key of the script key (e.g. for
120+ // imported proofs).
121+ ScriptKeyUnknown ScriptKeyType = 0
122+
123+ // ScriptKeyBip86 is the script key type used for assets that use the
124+ // BIP86 style tweak (e.g. an empty tweak).
125+ ScriptKeyBip86 ScriptKeyType = 1
126+
127+ // ScriptKeyScriptPathExternal is the script key type used for assets
128+ // that use a script path that is defined by an external application.
129+ // Keys with script paths are normally not shown in asset balances and
130+ // by default aren't used for coin selection unless specifically
131+ // requested.
132+ ScriptKeyScriptPathExternal ScriptKeyType = 2
133+
134+ // ScriptKeyBurn is the script key type used for assets that are burned
135+ // and not spendable.
136+ ScriptKeyBurn ScriptKeyType = 3
137+
138+ // ScriptKeyTombstone is the script key type used for assets that are
139+ // not spendable and have been marked as tombstones. This is only the
140+ // case for zero-value assets that result from a non-interactive (TAP
141+ // address) send where no change was left over. The script key used for
142+ // this is a NUMS key that is not spendable.
143+ ScriptKeyTombstone ScriptKeyType = 4
144+
145+ // ScriptKeyScriptPathChannel is the script key type used for assets
146+ // that use a script path that is somehow related to Taproot Asset
147+ // Channels. That means the script key is either a funding key
148+ // (OP_TRUE), a commitment output key (to_local, to_remote, htlc), or a
149+ // HTLC second-level transaction output key.
150+ // Keys related to channels are not shown in asset balances (unless
151+ // specifically requested) and are _never_ used for coin selection.
152+ ScriptKeyScriptPathChannel ScriptKeyType = 5
153+ )
154+
111155var (
112156 // ZeroPrevID is the blank prev ID used for genesis assets and also
113157 // asset split leaves.
@@ -984,6 +1028,9 @@ type TweakedScriptKey struct {
9841028 // flag has is that assets with a declared key are shown in the asset
9851029 // list/balance.
9861030 DeclaredKnown bool
1031+
1032+ // Type is the type of script key that is being used.
1033+ Type ScriptKeyType
9871034}
9881035
9891036// IsEqual returns true is this tweaked script key is exactly equivalent to the
@@ -1069,15 +1116,49 @@ func (s *ScriptKey) HasScriptPath() bool {
10691116 return s .TweakedScriptKey != nil && len (s .TweakedScriptKey .Tweak ) > 0
10701117}
10711118
1119+ // GuessType tries to guess the type of the script key based on the information
1120+ // available.
1121+ func (s * ScriptKey ) GuessType () ScriptKeyType {
1122+ // If we have an explicit script key type set, we can return that.
1123+ if s .TweakedScriptKey != nil &&
1124+ s .TweakedScriptKey .Type != ScriptKeyUnknown {
1125+
1126+ return s .TweakedScriptKey .Type
1127+ }
1128+
1129+ // If there is a known tweak, then we know that this is a script path
1130+ // key. We never return the channel type, since those keys should always
1131+ // be declared properly, and we never should need to guess their type.
1132+ if s .HasScriptPath () {
1133+ return ScriptKeyScriptPathExternal
1134+ }
1135+
1136+ // Is it the known NUMS key? Then this is a tombstone output.
1137+ if s .PubKey != nil && s .PubKey .IsEqual (NUMSPubKey ) {
1138+ return ScriptKeyTombstone
1139+ }
1140+
1141+ // Do we know the internal key? Then we can check whether it is a
1142+ // BIP-0086 key.
1143+ if s .PubKey != nil && s .TweakedScriptKey != nil &&
1144+ s .TweakedScriptKey .RawKey .PubKey != nil {
1145+
1146+ bip86 := NewScriptKeyBip86 (s .TweakedScriptKey .RawKey )
1147+ if bip86 .PubKey .IsEqual (s .PubKey ) {
1148+ return ScriptKeyBip86
1149+ }
1150+ }
1151+
1152+ return ScriptKeyUnknown
1153+ }
1154+
10721155// NewScriptKey constructs a ScriptKey with only the publicly available
10731156// information. This resulting key may or may not have a tweak applied to it.
10741157func NewScriptKey (key * btcec.PublicKey ) ScriptKey {
10751158 // Since we'll never query lnd for a tweaked key, it doesn't matter if
10761159 // we lose the parity information here. And this will only ever be
10771160 // serialized on chain in a 32-bit representation as well.
1078- key , _ = schnorr .ParsePubKey (
1079- schnorr .SerializePubKey (key ),
1080- )
1161+ key , _ = schnorr .ParsePubKey (schnorr .SerializePubKey (key ))
10811162 return ScriptKey {
10821163 PubKey : key ,
10831164 }
@@ -1089,9 +1170,7 @@ func NewScriptKey(key *btcec.PublicKey) ScriptKey {
10891170func NewScriptKeyBip86 (rawKey keychain.KeyDescriptor ) ScriptKey {
10901171 // Tweak the script key BIP-0086 style (such that we only commit to the
10911172 // internal key when signing).
1092- tweakedPubKey := txscript .ComputeTaprootKeyNoScript (
1093- rawKey .PubKey ,
1094- )
1173+ tweakedPubKey := txscript .ComputeTaprootKeyNoScript (rawKey .PubKey )
10951174
10961175 // Since we'll never query lnd for a tweaked key, it doesn't matter if
10971176 // we lose the parity information here. And this will only ever be
@@ -1104,6 +1183,7 @@ func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey {
11041183 PubKey : tweakedPubKey ,
11051184 TweakedScriptKey : & TweakedScriptKey {
11061185 RawKey : rawKey ,
1186+ Type : ScriptKeyBip86 ,
11071187 },
11081188 }
11091189}
@@ -1491,6 +1571,7 @@ func (a *Asset) Copy() *Asset {
14911571 if a .ScriptKey .TweakedScriptKey != nil {
14921572 assetCopy .ScriptKey .TweakedScriptKey = & TweakedScriptKey {
14931573 DeclaredKnown : a .ScriptKey .DeclaredKnown ,
1574+ Type : a .ScriptKey .Type ,
14941575 }
14951576 assetCopy .ScriptKey .RawKey = a .ScriptKey .RawKey
14961577
0 commit comments