diff --git a/faucet.go b/faucet.go index df59576..8b74ecf 100644 --- a/faucet.go +++ b/faucet.go @@ -30,9 +30,10 @@ type Faucet struct { mux *chi.Mux // HTTP routing - config *config.Config // faucet configuration - middlewares []Middleware // request middlewares - handlers []Handler // request handlers + config *config.Config // faucet configuration + middlewares []Middleware // request middlewares + handlers []Handler // request handlers + prepareTxMsgFn PrepareTxMessageFn // transaction message creator sendAmount std.Coins // for fast lookup } @@ -44,11 +45,12 @@ func NewFaucet( opts ...Option, ) (*Faucet, error) { f := &Faucet{ - estimator: estimator, - client: client, - logger: noop.New(), - config: config.DefaultConfig(), - middlewares: nil, // no middlewares by default + estimator: estimator, + client: client, + logger: noop.New(), + config: config.DefaultConfig(), + prepareTxMsgFn: defaultPrepareTxMessage, + middlewares: nil, // no middlewares by default mux: chi.NewMux(), } diff --git a/faucet_test.go b/faucet_test.go index 5130248..6e17d3a 100644 --- a/faucet_test.go +++ b/faucet_test.go @@ -6,6 +6,9 @@ import ( "github.com/gnolang/faucet/config" "github.com/gnolang/faucet/log/noop" + "github.com/gnolang/gno/gno.land/pkg/sdk/vm" + "github.com/gnolang/gno/tm2/pkg/crypto" + "github.com/gnolang/gno/tm2/pkg/std" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -138,4 +141,52 @@ func TestFaucet_NewFaucet(t *testing.T) { assert.NotNil(t, f) assert.NoError(t, err) }) + + t.Run("with prepare transaction message callback", func(t *testing.T) { + t.Parallel() + + var ( + cfg = PrepareCfg{ + SendAmount: std.NewCoins(std.NewCoin("ugnot", 10)), + FromAddress: crypto.Address{1}, + ToAddress: crypto.Address{2}, + } + + pkgPath = "gno.land/r/demo/example" + pkgFunc = "FundPlayer" + + prepareTxMsgFn = func(cfg PrepareCfg) std.Msg { + return vm.MsgCall{ + Caller: cfg.FromAddress, + PkgPath: pkgPath, + Func: pkgFunc, + Args: []string{cfg.ToAddress.String()}, + Send: cfg.SendAmount, + } + } + ) + + f, err := NewFaucet( + &mockEstimator{}, + &mockClient{}, + WithConfig(config.DefaultConfig()), + WithPrepareTxMessageFn(prepareTxMsgFn), + ) + + require.NotNil(t, f) + require.NoError(t, err) + + // Prepare the message + msg := f.prepareTxMsgFn(cfg) + + // Validate the message + msgCall, ok := msg.(vm.MsgCall) + require.True(t, ok) + + assert.Equal(t, cfg.FromAddress, msgCall.Caller) + assert.Equal(t, pkgPath, msgCall.PkgPath) + assert.Equal(t, pkgFunc, msgCall.Func) + assert.Equal(t, []string{cfg.ToAddress.String()}, msgCall.Args) + assert.Equal(t, cfg.SendAmount, msgCall.Send) + }) } diff --git a/go.mod b/go.mod index a152391..7c4d04d 100644 --- a/go.mod +++ b/go.mod @@ -18,6 +18,7 @@ require ( github.com/btcsuite/btcd/btcutil v1.0.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.1.1 // indirect + github.com/cockroachdb/apd v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dgraph-io/badger/v3 v3.2103.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect @@ -45,6 +46,7 @@ require ( golang.org/x/mod v0.12.0 // indirect golang.org/x/net v0.15.0 // indirect golang.org/x/sys v0.12.0 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index c130f32..ba96b8e 100644 --- a/go.sum +++ b/go.sum @@ -22,6 +22,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -94,6 +96,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= github.com/linxGnu/grocksdb v1.8.4 h1:ZMsBpPpJNtRLHiKKp0mI7gW+NT4s7UgfD5xHxx1jVRo= @@ -203,6 +206,8 @@ golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/handler.go b/handler.go index 101339f..e1b9828 100644 --- a/handler.go +++ b/handler.go @@ -74,7 +74,7 @@ func (f *Faucet) handleRequest(writer writer.ResponseWriter, requests Requests) continue } - // Run the method methodHandler + // Run the method handler if err := f.transferFunds(beneficiary); err != nil { f.logger.Debug( unableToHandleRequest, diff --git a/options.go b/options.go index 212ad9e..c721150 100644 --- a/options.go +++ b/options.go @@ -34,3 +34,11 @@ func WithHandlers(handlers []Handler) Option { f.handlers = append(f.handlers, handlers...) } } + +// WithPrepareTxMessageFn specifies the faucet +// transaction message constructor +func WithPrepareTxMessageFn(prepareTxMsgFn PrepareTxMessageFn) Option { + return func(f *Faucet) { + f.prepareTxMsgFn = prepareTxMsgFn + } +} diff --git a/prepare.go b/prepare.go index 69e3fd1..b0a3603 100644 --- a/prepare.go +++ b/prepare.go @@ -7,28 +7,33 @@ import ( "github.com/gnolang/gno/tm2/pkg/std" ) -// prepareCfg specifies the tx prepare configuration -type prepareCfg struct { - sendAmount std.Coins // the amount to be sent - fromAddress crypto.Address // the faucet address - toAddress crypto.Address // the beneficiary address +// PrepareTxMessageFn is the callback method that +// constructs the faucet fund transaction message +type PrepareTxMessageFn func(PrepareCfg) std.Msg + +// PrepareCfg specifies the tx prepare configuration +type PrepareCfg struct { + SendAmount std.Coins // the amount to be sent + FromAddress crypto.Address // the faucet address + ToAddress crypto.Address // the beneficiary address +} + +// defaultPrepareTxMessage constructs the default +// native currency transfer message +func defaultPrepareTxMessage(cfg PrepareCfg) std.Msg { + return bank.MsgSend{ + FromAddress: cfg.FromAddress, + ToAddress: cfg.ToAddress, + Amount: cfg.SendAmount, + } } // prepareTransaction prepares the transaction for signing func prepareTransaction( estimator estimate.Estimator, - cfg prepareCfg, + msg std.Msg, ) *std.Tx { // Construct the transaction - msg := vm.MsgCall{ - FromAddress: cfg.fromAddress, - ToAddress: cfg.toAddress, - PkgAddr: "gno.land/r/demo/chess/register", - Func: "RegisterPlayer", - Args: []string{"calleraddr", "token"}, - Send: cfg.sendAmount, - } - tx := &std.Tx{ Msgs: []std.Msg{msg}, Signatures: nil, diff --git a/prepare_test.go b/prepare_test.go index 7cb5b03..c45e178 100644 --- a/prepare_test.go +++ b/prepare_test.go @@ -36,13 +36,13 @@ func TestPrepareTransaction(t *testing.T) { ) // Prepare the transaction - cfg := prepareCfg{ - fromAddress: fromAddress, - toAddress: toAddress, - sendAmount: sendAmount, + cfg := PrepareCfg{ + FromAddress: fromAddress, + ToAddress: toAddress, + SendAmount: sendAmount, } - tx := prepareTransaction(mockEstimator, cfg) + tx := prepareTransaction(mockEstimator, defaultPrepareTxMessage(cfg)) // Make sure the transaction was created require.NotNil(t, tx) diff --git a/transfer.go b/transfer.go index 94c4f46..cb62076 100644 --- a/transfer.go +++ b/transfer.go @@ -18,12 +18,12 @@ func (f *Faucet) transferFunds(address crypto.Address) error { } // Prepare the transaction - pCfg := prepareCfg{ - fromAddress: fundAccount.GetAddress(), - toAddress: address, - sendAmount: f.sendAmount, + pCfg := PrepareCfg{ + FromAddress: fundAccount.GetAddress(), + ToAddress: address, + SendAmount: f.sendAmount, } - tx := prepareTransaction(f.estimator, pCfg) + tx := prepareTransaction(f.estimator, f.prepareTxMsgFn(pCfg)) // Sign the transaction sCfg := signCfg{