swag/server: implement z_sendmany call
This commit is contained in:
parent
77a8362811
commit
a5c472e815
104
swag/server.go
104
swag/server.go
|
@ -2,23 +2,111 @@ package swag
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/btcsuite/btcd/rpcclient"
|
||||
"github.com/zcash-hackworks/zcon1-swag-api/api"
|
||||
)
|
||||
|
||||
const (
|
||||
swagFromAddress = "TODO HARDCODED FROM ADDRESS"
|
||||
swagDefaultAmount = 1
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
rpc *rpcclient.Client
|
||||
}
|
||||
|
||||
func NewServer(dbPath string, zc *rpcclient.Client) (api.SwagAPIServer, error) {
|
||||
return &Server{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Redeem(ctx context.Context, req *api.Request) (*api.Response, error) {
|
||||
return &api.Response{
|
||||
Success: true,
|
||||
Msg: "hello",
|
||||
func NewServer(dbPath string, rpc *rpcclient.Client) (api.SwagAPIServer, error) {
|
||||
// TODO: CREATE AND POPULATE THE DATABASE
|
||||
return &Server{
|
||||
rpc: rpc,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Redeem(ctx context.Context, req *api.Request) (*api.Response, error) {
|
||||
|
||||
// TODO: QUERY THE DATABASE
|
||||
|
||||
return s.TriggerSend(ctx, req)
|
||||
}
|
||||
|
||||
func (s *Server) GracefulStop() {}
|
||||
|
||||
type zSendManyDest struct {
|
||||
Address string `json:"address"`
|
||||
Amount int64 `json:"amount"`
|
||||
}
|
||||
|
||||
func (s *Server) TriggerSend(ctx context.Context, req *api.Request) (*api.Response, error) {
|
||||
// z_sendmany "fromaddress" [{"address":... ,"amount":...},...] ( minconf ) ( fee )
|
||||
//
|
||||
// Send multiple times. Amounts are decimal numbers with at most 8 digits of precision.
|
||||
// Change generated from a taddr flows to a new taddr address, while change generated from a zaddr returns to itself.
|
||||
// When sending coinbase UTXOs to a zaddr, change is not allowed. The entire value of the UTXO(s) must be consumed.
|
||||
// Before Sapling activates, the maximum number of zaddr outputs is 54 due to transaction size limits.
|
||||
//
|
||||
// Arguments:
|
||||
// 1. "fromaddress" (string, required) The taddr or zaddr to send the funds from.
|
||||
// 2. "amounts" (array, required) An array of json objects representing the amounts to send.
|
||||
// [{
|
||||
// "address":address (string, required) The address is a taddr or zaddr
|
||||
// "amount":amount (numeric, required) The numeric amount in ZEC is the value
|
||||
// "memo":memo (string, optional) If the address is a zaddr, raw data represented in hexadecimal string format
|
||||
// }, ... ]
|
||||
// 3. minconf (numeric, optional, default=1) Only use funds confirmed at least this many times.
|
||||
// 4. fee (numeric, optional, default=0.0001) The fee amount to attach to this transaction.
|
||||
//
|
||||
// Result:
|
||||
// "operationid" (string) An operationid to pass to z_getoperationstatus to get the result of the operation.
|
||||
//
|
||||
// Examples:
|
||||
// > zcash-cli z_sendmany "t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd" '[{"address": "ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf" ,"amount": 5.0}]'
|
||||
// > curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "z_sendmany", "params": ["t1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd", [{"address": "ztfaW34Gj9FrnGUEf833ywDVL62NWXBM81u6EQnM6VR45eYnXhwztecW1SjxA7JrmAXKJhxhj3vDNEpVCQoSvVoSpmbhtjf" ,"amount": 5.0}]] }' -H 'content-type: text/plain;' http://127.0.0.1:8232/
|
||||
|
||||
// Construct raw JSON-RPC params. This is VERY UGLY because the btcd library lacks direct support for our RPC calls.
|
||||
|
||||
zDests := make([]zSendManyDest, 1)
|
||||
zDests[0] = zSendManyDest{
|
||||
Address: req.Address,
|
||||
Amount: swagDefaultAmount,
|
||||
}
|
||||
|
||||
encodedDests, err := json.Marshal(zDests)
|
||||
if err != nil {
|
||||
return &api.Response{
|
||||
Success: false,
|
||||
Msg: "Couldn't initiate transaction successfully.",
|
||||
}, err
|
||||
}
|
||||
|
||||
params := make([]json.RawMessage, 2)
|
||||
params[0] = json.RawMessage("\"" + swagFromAddress + "\"")
|
||||
params[1] = json.RawMessage(encodedDests)
|
||||
result, rpcErr := s.rpc.RawRequest("z_sendmany", params)
|
||||
|
||||
// For some reason, the error responses are not JSON
|
||||
if rpcErr != nil {
|
||||
errParts := strings.SplitN(rpcErr.Error(), ":", 2)
|
||||
errMsg := strings.TrimSpace(errParts[1])
|
||||
_, err = strconv.ParseInt(errParts[0], 10, 32)
|
||||
if err != nil {
|
||||
// This should never happen. We can't panic here, but it's that class of error.
|
||||
// This is why we need integration testing to work better than regtest currently does. TODO.
|
||||
return nil, errors.New("SendTransaction couldn't parse error code")
|
||||
}
|
||||
|
||||
return &api.Response{
|
||||
Success: false,
|
||||
Msg: errMsg,
|
||||
}, rpcErr
|
||||
}
|
||||
|
||||
return &api.Response{
|
||||
Success: true,
|
||||
Msg: string(result),
|
||||
}, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue