github.com/mavryk-network/mvgo@v1.19.9/internal/compose/alpha/task/token_approve.go (about)

     1  // Copyright (c) 2023 Blockwatch Data Inc.
     2  // Author: alex@blockwatch.cc, abdul@blockwatch.cc
     3  
     4  package task
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/mavryk-network/mvgo/codec"
    10  	"github.com/mavryk-network/mvgo/contract"
    11  	"github.com/mavryk-network/mvgo/internal/compose"
    12  	"github.com/mavryk-network/mvgo/internal/compose/alpha"
    13  	"github.com/mavryk-network/mvgo/mavryk"
    14  	"github.com/mavryk-network/mvgo/rpc"
    15  	"github.com/mavryk-network/mvgo/signer"
    16  
    17  	"github.com/pkg/errors"
    18  )
    19  
    20  var _ alpha.TaskBuilder = (*TokenApproveTask)(nil)
    21  
    22  func init() {
    23  	alpha.RegisterTask("token_approve", NewTokenApproveTask)
    24  }
    25  
    26  type TokenApproveTask struct {
    27  	TargetTask
    28  	Spender  mavryk.Address
    29  	Standard string
    30  	Amount   mavryk.Z
    31  	TokenId  mavryk.Z
    32  }
    33  
    34  func NewTokenApproveTask() alpha.TaskBuilder {
    35  	return &TokenApproveTask{}
    36  }
    37  
    38  func (t *TokenApproveTask) Type() string {
    39  	return "token_approve"
    40  }
    41  
    42  func (t *TokenApproveTask) Build(ctx compose.Context, task alpha.Task) (*codec.Op, *rpc.CallOptions, error) {
    43  	if err := t.parse(ctx, task); err != nil {
    44  		return nil, nil, errors.Wrap(err, "parse")
    45  	}
    46  	var xfer codec.Operation
    47  	switch t.Standard {
    48  	case "fa2", "":
    49  		xfer = contract.NewFA2ApprovalArgs().
    50  			AddOperator(t.Source, t.Spender, t.TokenId).
    51  			WithSource(t.Source).
    52  			WithDestination(t.Destination).
    53  			Encode()
    54  	case "fa1", "fa12", "fa1.2":
    55  		xfer = contract.NewFA1ApprovalArgs().
    56  			Approve(t.Spender, t.Amount).
    57  			WithSource(t.Source).
    58  			WithDestination(t.Destination).
    59  			Encode()
    60  	}
    61  
    62  	opts := rpc.NewCallOptions()
    63  	opts.Signer = signer.NewFromKey(t.Key)
    64  	op := codec.NewOp().WithContents(xfer)
    65  	return op, opts, nil
    66  }
    67  
    68  func (t *TokenApproveTask) Validate(ctx compose.Context, task alpha.Task) error {
    69  	return t.parse(ctx, task)
    70  }
    71  
    72  func (t *TokenApproveTask) parse(ctx compose.Context, task alpha.Task) (err error) {
    73  	if err = t.TargetTask.parse(ctx, task); err != nil {
    74  		return err
    75  	}
    76  	if t.Standard, err = ctx.ResolveString(task.Args["standard"]); err != nil {
    77  		return errors.Wrap(err, "standard")
    78  	}
    79  	switch t.Standard {
    80  	case "fa2", "", "fa1", "fa12", "fa1.2":
    81  		// skip
    82  	default:
    83  		return fmt.Errorf("unsupported token standard %s", t.Standard)
    84  	}
    85  	if t.Spender, err = ctx.ResolveAddress(task.Args["spender"]); err != nil {
    86  		return errors.Wrap(err, "spender")
    87  	}
    88  	// only required for fa2
    89  	switch t.Standard {
    90  	case "fa2", "":
    91  		if t.TokenId, err = ctx.ResolveZ(task.Args["token_id"]); err != nil {
    92  			return errors.Wrap(err, "token_id")
    93  		}
    94  	default:
    95  		if t.Amount, err = ctx.ResolveZ(task.Args["amount"]); err != nil {
    96  			return errors.Wrap(err, "amount")
    97  		}
    98  	}
    99  	return
   100  }