@@ -108,6 +108,43 @@ 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+ // ScriptKeyScriptPathChannel is the script key type used for assets
139+ // that use a script path that is somehow related to Taproot Asset
140+ // Channels. That means the script key is either a funding key
141+ // (OP_TRUE), a commitment output key (to_local, to_remote, htlc), or a
142+ // HTLC second-level transaction output key.
143+ // Keys related to channels are not shown in asset balances (unless
144+ // specifically requested) and _never_ used for coin selection.
145+ ScriptKeyScriptPathChannel ScriptKeyType = 4
146+ )
147+
111148var (
112149 // ZeroPrevID is the blank prev ID used for genesis assets and also
113150 // asset split leaves.
@@ -984,6 +1021,9 @@ type TweakedScriptKey struct {
9841021 // flag has is that assets with a declared key are shown in the asset
9851022 // list/balance.
9861023 DeclaredKnown bool
1024+
1025+ // Type is the type of script key that is being used.
1026+ Type ScriptKeyType
9871027}
9881028
9891029// IsEqual returns true is this tweaked script key is exactly equivalent to the
@@ -1069,15 +1109,44 @@ func (s *ScriptKey) HasScriptPath() bool {
10691109 return s .TweakedScriptKey != nil && len (s .TweakedScriptKey .Tweak ) > 0
10701110}
10711111
1112+ // GuessType tries to guess the type of the script key based on the information
1113+ // available.
1114+ func (s * ScriptKey ) GuessType () ScriptKeyType {
1115+ // If we have an explicit script key type set, we can return that.
1116+ if s .TweakedScriptKey != nil &&
1117+ s .TweakedScriptKey .Type != ScriptKeyUnknown {
1118+
1119+ return s .TweakedScriptKey .Type
1120+ }
1121+
1122+ // If there is a known tweak, then we know that this is a script path
1123+ // key. We never return the channel type, since those keys should always
1124+ // be declared properly, and we never should need to guess their type.
1125+ if s .HasScriptPath () {
1126+ return ScriptKeyScriptPathExternal
1127+ }
1128+
1129+ // Do we know the internal key? Then we can check whether it is a
1130+ // BIP-0086 key.
1131+ if s .PubKey != nil && s .TweakedScriptKey != nil &&
1132+ s .TweakedScriptKey .RawKey .PubKey != nil {
1133+
1134+ bip86 := NewScriptKeyBip86 (s .TweakedScriptKey .RawKey )
1135+ if bip86 .PubKey .IsEqual (s .PubKey ) {
1136+ return ScriptKeyBip86
1137+ }
1138+ }
1139+
1140+ return ScriptKeyUnknown
1141+ }
1142+
10721143// NewScriptKey constructs a ScriptKey with only the publicly available
10731144// information. This resulting key may or may not have a tweak applied to it.
10741145func NewScriptKey (key * btcec.PublicKey ) ScriptKey {
10751146 // Since we'll never query lnd for a tweaked key, it doesn't matter if
10761147 // we lose the parity information here. And this will only ever be
10771148 // serialized on chain in a 32-bit representation as well.
1078- key , _ = schnorr .ParsePubKey (
1079- schnorr .SerializePubKey (key ),
1080- )
1149+ key , _ = schnorr .ParsePubKey (schnorr .SerializePubKey (key ))
10811150 return ScriptKey {
10821151 PubKey : key ,
10831152 }
@@ -1089,9 +1158,7 @@ func NewScriptKey(key *btcec.PublicKey) ScriptKey {
10891158func NewScriptKeyBip86 (rawKey keychain.KeyDescriptor ) ScriptKey {
10901159 // Tweak the script key BIP-0086 style (such that we only commit to the
10911160 // internal key when signing).
1092- tweakedPubKey := txscript .ComputeTaprootKeyNoScript (
1093- rawKey .PubKey ,
1094- )
1161+ tweakedPubKey := txscript .ComputeTaprootKeyNoScript (rawKey .PubKey )
10951162
10961163 // Since we'll never query lnd for a tweaked key, it doesn't matter if
10971164 // we lose the parity information here. And this will only ever be
@@ -1104,6 +1171,7 @@ func NewScriptKeyBip86(rawKey keychain.KeyDescriptor) ScriptKey {
11041171 PubKey : tweakedPubKey ,
11051172 TweakedScriptKey : & TweakedScriptKey {
11061173 RawKey : rawKey ,
1174+ Type : ScriptKeyBip86 ,
11071175 },
11081176 }
11091177}
0 commit comments