Files
zeekayandHanzo Dev 3b9e1149ec lint: clean all 21 staticcheck findings — CI green, drop last codec reference
- SA1019: math.Mul64/Add64 -> generic math.Mul/Add (ed25519fx, mldsafx,
  schnorrfx inputs; flow_checker; utxo_fetching); prefixdb.NewNested -> New (alias)
- unused: DELETE dead codecVersion const (last codec reference in utxo — full
  ZAP native now), isSortedAndUniqueOrdered (root + secp256k1fx), mldsafx
  Keychain.get, and all 6 redundant TransferOutput.isState() markers (the
  embedded verify.IsState already provides State membership)
- QF1008: drop embedded-field selectors (utxo_wire, ed25519fx, nftfx,
  propertyfx + tests); ST1005: lowercase Schnorr error string

Behavior-identical; 11/11 packages pass.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-12 22:32:45 -07:00

105 lines
2.7 KiB
Go

// Copyright (C) 2019-2025, Lux Industries, Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package nftfx
import (
"bytes"
"errors"
"github.com/luxfi/utxo/secp256k1fx"
"github.com/luxfi/vm/components/verify"
)
var (
errWrongTxType = errors.New("wrong tx type")
errWrongUTXOType = errors.New("wrong utxo type")
errWrongOperationType = errors.New("wrong operation type")
errWrongCredentialType = errors.New("wrong credential type")
errWrongNumberOfUTXOs = errors.New("wrong number of UTXOs for the operation")
errWrongUniqueID = errors.New("wrong unique ID provided")
errWrongBytes = errors.New("wrong bytes provided")
errCantTransfer = errors.New("cant transfer with this fx")
)
type Fx struct{ secp256k1fx.Fx }
func (fx *Fx) Initialize(vmIntf interface{}) error {
if err := fx.InitializeVM(vmIntf); err != nil {
return err
}
log := fx.VM.Logger()
log.Debug("initializing nft fx")
// ZAP-native: wire schemas are compile-time static. No runtime
// codec registration needed.
return nil
}
func (fx *Fx) VerifyOperation(txIntf, opIntf, credIntf interface{}, utxosIntf []interface{}) error {
tx, ok := txIntf.(secp256k1fx.UnsignedTx)
switch {
case !ok:
return errWrongTxType
case len(utxosIntf) != 1:
return errWrongNumberOfUTXOs
}
cred, ok := credIntf.(*Credential)
if !ok {
return errWrongCredentialType
}
switch op := opIntf.(type) {
case *MintOperation:
return fx.VerifyMintOperation(tx, op, cred, utxosIntf[0])
case *TransferOperation:
return fx.VerifyTransferOperation(tx, op, cred, utxosIntf[0])
default:
return errWrongOperationType
}
}
func (fx *Fx) VerifyMintOperation(tx secp256k1fx.UnsignedTx, op *MintOperation, cred *Credential, utxoIntf interface{}) error {
out, ok := utxoIntf.(*MintOutput)
if !ok {
return errWrongUTXOType
}
if err := verify.All(op, cred, out); err != nil {
return err
}
switch {
case out.GroupID != op.GroupID:
return errWrongUniqueID
default:
return fx.VerifyCredentials(tx, &op.MintInput, &cred.Credential, &out.OutputOwners)
}
}
func (fx *Fx) VerifyTransferOperation(tx secp256k1fx.UnsignedTx, op *TransferOperation, cred *Credential, utxoIntf interface{}) error {
out, ok := utxoIntf.(*TransferOutput)
if !ok {
return errWrongUTXOType
}
if err := verify.All(op, cred, out); err != nil {
return err
}
switch {
case out.GroupID != op.Output.GroupID:
return errWrongUniqueID
case !bytes.Equal(out.Payload, op.Output.Payload):
return errWrongBytes
default:
return fx.VerifyCredentials(tx, &op.Input, &cred.Credential, &out.OutputOwners)
}
}
func (*Fx) VerifyTransfer(_, _, _, _ interface{}) error {
return errCantTransfer
}