mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-18 12:44:19 +01:00
Move redeem transactions creation client-side (#388)
* move OOR transaction creation client-side * robust redeem tx checks * optimize GetVtxos db call * rename CompleteAsyncPayment --> SubmitRedeemTx * fix permissions.go
This commit is contained in:
@@ -3,11 +3,12 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
arkv1 "github.com/ark-network/ark/api-spec/protobuf/gen/ark/v1"
|
||||
"github.com/ark-network/ark/common/bitcointree"
|
||||
"github.com/ark-network/ark/common/descriptor"
|
||||
@@ -309,61 +310,25 @@ func (h *handler) Ping(
|
||||
return &arkv1.PingResponse{}, nil
|
||||
}
|
||||
|
||||
func (h *handler) CreatePayment(
|
||||
ctx context.Context, req *arkv1.CreatePaymentRequest,
|
||||
) (*arkv1.CreatePaymentResponse, error) {
|
||||
inputs, err := parseAsyncPaymentInputs(req.GetInputs())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
func (h *handler) SubmitRedeemTx(
|
||||
ctx context.Context, req *arkv1.SubmitRedeemTxRequest,
|
||||
) (*arkv1.SubmitRedeemTxResponse, error) {
|
||||
if req.GetRedeemTx() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "missing redeem tx")
|
||||
}
|
||||
|
||||
receivers, err := parseReceivers(req.GetOutputs())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
for _, receiver := range receivers {
|
||||
if receiver.Amount <= 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "output amount must be greater than 0")
|
||||
}
|
||||
|
||||
if len(receiver.OnchainAddress) <= 0 && len(receiver.Pubkey) <= 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "missing address")
|
||||
}
|
||||
|
||||
if receiver.IsOnchain() {
|
||||
return nil, status.Error(codes.InvalidArgument, "onchain outputs are not supported as async payment destination")
|
||||
}
|
||||
}
|
||||
|
||||
redeemTx, err := h.svc.CreateAsyncPayment(
|
||||
ctx, inputs, receivers,
|
||||
signedRedeemTx, err := h.svc.SubmitRedeemTx(
|
||||
ctx, req.GetRedeemTx(),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &arkv1.CreatePaymentResponse{
|
||||
SignedRedeemTx: redeemTx,
|
||||
return &arkv1.SubmitRedeemTxResponse{
|
||||
SignedRedeemTx: signedRedeemTx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (h *handler) CompletePayment(
|
||||
ctx context.Context, req *arkv1.CompletePaymentRequest,
|
||||
) (*arkv1.CompletePaymentResponse, error) {
|
||||
if req.GetSignedRedeemTx() == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "missing signed redeem tx")
|
||||
}
|
||||
|
||||
if err := h.svc.CompleteAsyncPayment(
|
||||
ctx, req.GetSignedRedeemTx(),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &arkv1.CompletePaymentResponse{}, nil
|
||||
}
|
||||
|
||||
func (h *handler) GetRound(
|
||||
ctx context.Context, req *arkv1.GetRoundRequest,
|
||||
) (*arkv1.GetRoundResponse, error) {
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"github.com/ark-network/ark/server/internal/core/domain"
|
||||
"github.com/ark-network/ark/server/internal/core/ports"
|
||||
"github.com/btcsuite/btcd/btcec/v2/schnorr"
|
||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||
"github.com/btcsuite/btcd/txscript"
|
||||
)
|
||||
|
||||
@@ -25,33 +24,6 @@ func parseAddress(addr string) (*common.Address, error) {
|
||||
return common.DecodeAddress(addr)
|
||||
}
|
||||
|
||||
func parseAsyncPaymentInputs(ins []*arkv1.AsyncPaymentInput) ([]application.AsyncPaymentInput, error) {
|
||||
if len(ins) <= 0 {
|
||||
return nil, fmt.Errorf("missing inputs")
|
||||
}
|
||||
|
||||
inputs := make([]application.AsyncPaymentInput, 0, len(ins))
|
||||
for _, input := range ins {
|
||||
forfeitLeafHash, err := chainhash.NewHashFromStr(input.GetForfeitLeafHash())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid forfeit leaf hash: %s", err)
|
||||
}
|
||||
|
||||
inputs = append(inputs, application.AsyncPaymentInput{
|
||||
Input: ports.Input{
|
||||
VtxoKey: domain.VtxoKey{
|
||||
Txid: input.GetInput().GetOutpoint().GetTxid(),
|
||||
VOut: input.GetInput().GetOutpoint().GetVout(),
|
||||
},
|
||||
Tapscripts: input.GetInput().GetTapscripts().GetScripts(),
|
||||
},
|
||||
ForfeitLeafHash: *forfeitLeafHash,
|
||||
})
|
||||
}
|
||||
|
||||
return inputs, nil
|
||||
}
|
||||
|
||||
func parseNotes(notes []string) ([]note.Note, error) {
|
||||
if len(notes) <= 0 {
|
||||
return nil, fmt.Errorf("missing notes")
|
||||
|
||||
@@ -145,11 +145,7 @@ func Whitelist() map[string][]bakery.Op {
|
||||
Entity: EntityArk,
|
||||
Action: "read",
|
||||
}},
|
||||
fmt.Sprintf("/%s/CreatePayment", arkv1.ArkService_ServiceDesc.ServiceName): {{
|
||||
Entity: EntityArk,
|
||||
Action: "write",
|
||||
}},
|
||||
fmt.Sprintf("/%s/CompletePayment", arkv1.ArkService_ServiceDesc.ServiceName): {{
|
||||
fmt.Sprintf("/%s/SubmitRedeemTx", arkv1.ArkService_ServiceDesc.ServiceName): {{
|
||||
Entity: EntityArk,
|
||||
Action: "write",
|
||||
}},
|
||||
|
||||
Reference in New Issue
Block a user