mirror of
https://github.com/aljazceru/ark.git
synced 2025-12-17 12:14:21 +01:00
Drop unconditional forfeits txs in offline payment (#344)
* remove unconditionnal forfeit tx * fix sqlite vtxo repo * remove pendingData struct * delete uncond_forfeits_tx table
This commit is contained in:
@@ -511,12 +511,6 @@
|
||||
"properties": {
|
||||
"signedRedeemTx": {
|
||||
"type": "string"
|
||||
},
|
||||
"signedUnconditionalForfeitTxs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -548,12 +542,6 @@
|
||||
"signedRedeemTx": {
|
||||
"type": "string",
|
||||
"title": "signed only by the ASP"
|
||||
},
|
||||
"usignedUnconditionalForfeitTxs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -735,20 +723,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1PendingPayment": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"redeemTx": {
|
||||
"type": "string"
|
||||
},
|
||||
"unconditionalForfeitTxs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1PingResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -1094,8 +1068,8 @@
|
||||
"pending": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"pendingData": {
|
||||
"$ref": "#/definitions/v1PendingPayment"
|
||||
"redeemTx": {
|
||||
"type": "string"
|
||||
},
|
||||
"amount": {
|
||||
"type": "string",
|
||||
|
||||
@@ -193,12 +193,10 @@ message CreatePaymentRequest {
|
||||
}
|
||||
message CreatePaymentResponse {
|
||||
string signed_redeem_tx = 1; // signed only by the ASP
|
||||
repeated string usigned_unconditional_forfeit_txs = 2;
|
||||
}
|
||||
|
||||
message CompletePaymentRequest {
|
||||
string signed_redeem_tx = 1;
|
||||
repeated string signed_unconditional_forfeit_txs = 2;
|
||||
}
|
||||
message CompletePaymentResponse {}
|
||||
|
||||
@@ -318,14 +316,10 @@ message Vtxo {
|
||||
int64 expire_at = 6;
|
||||
bool swept = 7;
|
||||
bool pending = 8;
|
||||
PendingPayment pending_data = 9;
|
||||
string redeem_tx = 9;
|
||||
uint64 amount = 10;
|
||||
}
|
||||
|
||||
message PendingPayment {
|
||||
string redeem_tx = 1;
|
||||
repeated string unconditional_forfeit_txs =2;
|
||||
}
|
||||
|
||||
message GetTransactionsStreamRequest {}
|
||||
message GetTransactionsStreamResponse {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,9 +42,9 @@ type ASPClient interface {
|
||||
Ping(ctx context.Context, paymentID string) (RoundEvent, error)
|
||||
CreatePayment(
|
||||
ctx context.Context, inputs []Input, outputs []Output,
|
||||
) (string, []string, error)
|
||||
) (string, error)
|
||||
CompletePayment(
|
||||
ctx context.Context, signedRedeemTx string, signedUnconditionalForfeitTxs []string,
|
||||
ctx context.Context, signedRedeemTx string,
|
||||
) error
|
||||
ListVtxos(ctx context.Context, addr string) ([]Vtxo, []Vtxo, error)
|
||||
GetRound(ctx context.Context, txID string) (*Round, error)
|
||||
@@ -80,14 +80,13 @@ type Input struct {
|
||||
|
||||
type Vtxo struct {
|
||||
Outpoint
|
||||
Descriptor string
|
||||
Amount uint64
|
||||
RoundTxid string
|
||||
ExpiresAt *time.Time
|
||||
RedeemTx string
|
||||
UnconditionalForfeitTxs []string
|
||||
Pending bool
|
||||
SpentBy string
|
||||
Descriptor string
|
||||
Amount uint64
|
||||
RoundTxid string
|
||||
ExpiresAt *time.Time
|
||||
RedeemTx string
|
||||
Pending bool
|
||||
SpentBy string
|
||||
}
|
||||
|
||||
type Output struct {
|
||||
|
||||
@@ -238,24 +238,23 @@ func (a *grpcClient) Ping(
|
||||
|
||||
func (a *grpcClient) CreatePayment(
|
||||
ctx context.Context, inputs []client.Input, outputs []client.Output,
|
||||
) (string, []string, error) {
|
||||
) (string, error) {
|
||||
req := &arkv1.CreatePaymentRequest{
|
||||
Inputs: ins(inputs).toProto(),
|
||||
Outputs: outs(outputs).toProto(),
|
||||
}
|
||||
resp, err := a.svc.CreatePayment(ctx, req)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return "", err
|
||||
}
|
||||
return resp.SignedRedeemTx, resp.UsignedUnconditionalForfeitTxs, nil
|
||||
return resp.SignedRedeemTx, nil
|
||||
}
|
||||
|
||||
func (a *grpcClient) CompletePayment(
|
||||
ctx context.Context, redeemTx string, signedForfeitTxs []string,
|
||||
ctx context.Context, redeemTx string,
|
||||
) error {
|
||||
req := &arkv1.CompletePaymentRequest{
|
||||
SignedRedeemTx: redeemTx,
|
||||
SignedUnconditionalForfeitTxs: signedForfeitTxs,
|
||||
SignedRedeemTx: redeemTx,
|
||||
}
|
||||
_, err := a.svc.CompletePayment(ctx, req)
|
||||
return err
|
||||
|
||||
@@ -118,25 +118,18 @@ func (v vtxo) toVtxo() client.Vtxo {
|
||||
t := time.Unix(v.GetExpireAt(), 0)
|
||||
expiresAt = &t
|
||||
}
|
||||
var redeemTx string
|
||||
var uncondForfeitTxs []string
|
||||
if v.GetPendingData() != nil {
|
||||
redeemTx = v.GetPendingData().GetRedeemTx()
|
||||
uncondForfeitTxs = v.GetPendingData().GetUnconditionalForfeitTxs()
|
||||
}
|
||||
return client.Vtxo{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: v.GetOutpoint().GetTxid(),
|
||||
VOut: v.GetOutpoint().GetVout(),
|
||||
},
|
||||
Amount: v.GetAmount(),
|
||||
RoundTxid: v.GetRoundTxid(),
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.GetPending(),
|
||||
RedeemTx: redeemTx,
|
||||
UnconditionalForfeitTxs: uncondForfeitTxs,
|
||||
SpentBy: v.GetSpentBy(),
|
||||
Descriptor: v.GetDescriptor_(),
|
||||
Amount: v.GetAmount(),
|
||||
RoundTxid: v.GetRoundTxid(),
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.GetPending(),
|
||||
RedeemTx: v.GetRedeemTx(),
|
||||
SpentBy: v.GetSpentBy(),
|
||||
Descriptor: v.GetDescriptor_(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +338,7 @@ func (a *restClient) Ping(
|
||||
|
||||
func (a *restClient) CreatePayment(
|
||||
ctx context.Context, inputs []client.Input, outputs []client.Output,
|
||||
) (string, []string, error) {
|
||||
) (string, error) {
|
||||
ins := make([]*models.V1Input, 0, len(inputs))
|
||||
for _, i := range inputs {
|
||||
ins = append(ins, &models.V1Input{
|
||||
@@ -365,21 +365,19 @@ func (a *restClient) CreatePayment(
|
||||
ark_service.NewArkServiceCreatePaymentParams().WithBody(&body),
|
||||
)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return "", err
|
||||
}
|
||||
return resp.GetPayload().SignedRedeemTx, resp.GetPayload().UsignedUnconditionalForfeitTxs, nil
|
||||
return resp.GetPayload().SignedRedeemTx, nil
|
||||
}
|
||||
|
||||
func (a *restClient) CompletePayment(
|
||||
ctx context.Context, signedRedeemTx string, signedUncondForfeitTxs []string,
|
||||
ctx context.Context, signedRedeemTx string,
|
||||
) error {
|
||||
req := &arkv1.CompletePaymentRequest{
|
||||
SignedRedeemTx: signedRedeemTx,
|
||||
SignedUnconditionalForfeitTxs: signedUncondForfeitTxs,
|
||||
SignedRedeemTx: signedRedeemTx,
|
||||
}
|
||||
body := models.V1CompletePaymentRequest{
|
||||
SignedRedeemTx: req.GetSignedRedeemTx(),
|
||||
SignedUnconditionalForfeitTxs: req.GetSignedUnconditionalForfeitTxs(),
|
||||
SignedRedeemTx: req.GetSignedRedeemTx(),
|
||||
}
|
||||
_, err := a.svc.ArkServiceCompletePayment(
|
||||
ark_service.NewArkServiceCompletePaymentParams().WithBody(&body),
|
||||
@@ -492,26 +490,18 @@ func (a *restClient) ListVtxos(
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var redeemTx string
|
||||
var uncondForfeitTxs []string
|
||||
if v.PendingData != nil {
|
||||
redeemTx = v.PendingData.RedeemTx
|
||||
uncondForfeitTxs = v.PendingData.UnconditionalForfeitTxs
|
||||
}
|
||||
|
||||
spendableVtxos = append(spendableVtxos, client.Vtxo{
|
||||
Outpoint: client.Outpoint{
|
||||
Txid: v.Outpoint.Txid,
|
||||
VOut: uint32(v.Outpoint.Vout),
|
||||
},
|
||||
Amount: uint64(amount),
|
||||
RoundTxid: v.RoundTxid,
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.Pending,
|
||||
RedeemTx: redeemTx,
|
||||
UnconditionalForfeitTxs: uncondForfeitTxs,
|
||||
SpentBy: v.SpentBy,
|
||||
Descriptor: v.Descriptor,
|
||||
Amount: uint64(amount),
|
||||
RoundTxid: v.RoundTxid,
|
||||
ExpiresAt: expiresAt,
|
||||
Pending: v.Pending,
|
||||
RedeemTx: v.RedeemTx,
|
||||
SpentBy: v.SpentBy,
|
||||
Descriptor: v.Descriptor,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,8 @@ type ClientService interface {
|
||||
|
||||
ArkServiceGetRoundByID(params *ArkServiceGetRoundByIDParams, opts ...ClientOption) (*ArkServiceGetRoundByIDOK, error)
|
||||
|
||||
ArkServiceGetTransactionsStream(params *ArkServiceGetTransactionsStreamParams, opts ...ClientOption) (*ArkServiceGetTransactionsStreamOK, error)
|
||||
|
||||
ArkServiceListVtxos(params *ArkServiceListVtxosParams, opts ...ClientOption) (*ArkServiceListVtxosOK, error)
|
||||
|
||||
ArkServicePing(params *ArkServicePingParams, opts ...ClientOption) (*ArkServicePingOK, error)
|
||||
@@ -344,6 +346,43 @@ func (a *Client) ArkServiceGetRoundByID(params *ArkServiceGetRoundByIDParams, op
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetTransactionsStream ark service get transactions stream API
|
||||
*/
|
||||
func (a *Client) ArkServiceGetTransactionsStream(params *ArkServiceGetTransactionsStreamParams, opts ...ClientOption) (*ArkServiceGetTransactionsStreamOK, error) {
|
||||
// TODO: Validate the params before sending
|
||||
if params == nil {
|
||||
params = NewArkServiceGetTransactionsStreamParams()
|
||||
}
|
||||
op := &runtime.ClientOperation{
|
||||
ID: "ArkService_GetTransactionsStream",
|
||||
Method: "GET",
|
||||
PathPattern: "/v1/transactions",
|
||||
ProducesMediaTypes: []string{"application/json"},
|
||||
ConsumesMediaTypes: []string{"application/json"},
|
||||
Schemes: []string{"http"},
|
||||
Params: params,
|
||||
Reader: &ArkServiceGetTransactionsStreamReader{formats: a.formats},
|
||||
Context: params.Context,
|
||||
Client: params.HTTPClient,
|
||||
}
|
||||
for _, opt := range opts {
|
||||
opt(op)
|
||||
}
|
||||
|
||||
result, err := a.transport.Submit(op)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
success, ok := result.(*ArkServiceGetTransactionsStreamOK)
|
||||
if ok {
|
||||
return success, nil
|
||||
}
|
||||
// unexpected success response
|
||||
unexpectedSuccess := result.(*ArkServiceGetTransactionsStreamDefault)
|
||||
return nil, runtime.NewAPIError("unexpected success response: content available as default response in error", unexpectedSuccess, unexpectedSuccess.Code())
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceListVtxos ark service list vtxos API
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
cr "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// NewArkServiceGetTransactionsStreamParams creates a new ArkServiceGetTransactionsStreamParams object,
|
||||
// with the default timeout for this client.
|
||||
//
|
||||
// Default values are not hydrated, since defaults are normally applied by the API server side.
|
||||
//
|
||||
// To enforce default values in parameter, use SetDefaults or WithDefaults.
|
||||
func NewArkServiceGetTransactionsStreamParams() *ArkServiceGetTransactionsStreamParams {
|
||||
return &ArkServiceGetTransactionsStreamParams{
|
||||
timeout: cr.DefaultTimeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetTransactionsStreamParamsWithTimeout creates a new ArkServiceGetTransactionsStreamParams object
|
||||
// with the ability to set a timeout on a request.
|
||||
func NewArkServiceGetTransactionsStreamParamsWithTimeout(timeout time.Duration) *ArkServiceGetTransactionsStreamParams {
|
||||
return &ArkServiceGetTransactionsStreamParams{
|
||||
timeout: timeout,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetTransactionsStreamParamsWithContext creates a new ArkServiceGetTransactionsStreamParams object
|
||||
// with the ability to set a context for a request.
|
||||
func NewArkServiceGetTransactionsStreamParamsWithContext(ctx context.Context) *ArkServiceGetTransactionsStreamParams {
|
||||
return &ArkServiceGetTransactionsStreamParams{
|
||||
Context: ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetTransactionsStreamParamsWithHTTPClient creates a new ArkServiceGetTransactionsStreamParams object
|
||||
// with the ability to set a custom HTTPClient for a request.
|
||||
func NewArkServiceGetTransactionsStreamParamsWithHTTPClient(client *http.Client) *ArkServiceGetTransactionsStreamParams {
|
||||
return &ArkServiceGetTransactionsStreamParams{
|
||||
HTTPClient: client,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetTransactionsStreamParams contains all the parameters to send to the API endpoint
|
||||
|
||||
for the ark service get transactions stream operation.
|
||||
|
||||
Typically these are written to a http.Request.
|
||||
*/
|
||||
type ArkServiceGetTransactionsStreamParams struct {
|
||||
timeout time.Duration
|
||||
Context context.Context
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
// WithDefaults hydrates default values in the ark service get transactions stream params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceGetTransactionsStreamParams) WithDefaults() *ArkServiceGetTransactionsStreamParams {
|
||||
o.SetDefaults()
|
||||
return o
|
||||
}
|
||||
|
||||
// SetDefaults hydrates default values in the ark service get transactions stream params (not the query body).
|
||||
//
|
||||
// All values with no default are reset to their zero value.
|
||||
func (o *ArkServiceGetTransactionsStreamParams) SetDefaults() {
|
||||
// no default values defined for this parameter
|
||||
}
|
||||
|
||||
// WithTimeout adds the timeout to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) WithTimeout(timeout time.Duration) *ArkServiceGetTransactionsStreamParams {
|
||||
o.SetTimeout(timeout)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetTimeout adds the timeout to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) SetTimeout(timeout time.Duration) {
|
||||
o.timeout = timeout
|
||||
}
|
||||
|
||||
// WithContext adds the context to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) WithContext(ctx context.Context) *ArkServiceGetTransactionsStreamParams {
|
||||
o.SetContext(ctx)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetContext adds the context to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) SetContext(ctx context.Context) {
|
||||
o.Context = ctx
|
||||
}
|
||||
|
||||
// WithHTTPClient adds the HTTPClient to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) WithHTTPClient(client *http.Client) *ArkServiceGetTransactionsStreamParams {
|
||||
o.SetHTTPClient(client)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetHTTPClient adds the HTTPClient to the ark service get transactions stream params
|
||||
func (o *ArkServiceGetTransactionsStreamParams) SetHTTPClient(client *http.Client) {
|
||||
o.HTTPClient = client
|
||||
}
|
||||
|
||||
// WriteToRequest writes these params to a swagger request
|
||||
func (o *ArkServiceGetTransactionsStreamParams) WriteToRequest(r runtime.ClientRequest, reg strfmt.Registry) error {
|
||||
|
||||
if err := r.SetTimeout(o.timeout); err != nil {
|
||||
return err
|
||||
}
|
||||
var res []error
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package ark_service
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
|
||||
"github.com/ark-network/ark/pkg/client-sdk/client/rest/service/models"
|
||||
)
|
||||
|
||||
// ArkServiceGetTransactionsStreamReader is a Reader for the ArkServiceGetTransactionsStream structure.
|
||||
type ArkServiceGetTransactionsStreamReader struct {
|
||||
formats strfmt.Registry
|
||||
}
|
||||
|
||||
// ReadResponse reads a server response into the received o.
|
||||
func (o *ArkServiceGetTransactionsStreamReader) ReadResponse(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) {
|
||||
switch response.Code() {
|
||||
case 200:
|
||||
result := NewArkServiceGetTransactionsStreamOK()
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
default:
|
||||
result := NewArkServiceGetTransactionsStreamDefault(response.Code())
|
||||
if err := result.readResponse(response, consumer, o.formats); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if response.Code()/100 == 2 {
|
||||
return result, nil
|
||||
}
|
||||
return nil, result
|
||||
}
|
||||
}
|
||||
|
||||
// NewArkServiceGetTransactionsStreamOK creates a ArkServiceGetTransactionsStreamOK with default headers values
|
||||
func NewArkServiceGetTransactionsStreamOK() *ArkServiceGetTransactionsStreamOK {
|
||||
return &ArkServiceGetTransactionsStreamOK{}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetTransactionsStreamOK describes a response with status code 200, with default header values.
|
||||
|
||||
A successful response.(streaming responses)
|
||||
*/
|
||||
type ArkServiceGetTransactionsStreamOK struct {
|
||||
Payload *ArkServiceGetTransactionsStreamOKBody
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service get transactions stream o k response has a 2xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamOK) IsSuccess() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service get transactions stream o k response has a 3xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamOK) IsRedirect() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service get transactions stream o k response has a 4xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamOK) IsClientError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service get transactions stream o k response has a 5xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamOK) IsServerError() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service get transactions stream o k response a status code equal to that given
|
||||
func (o *ArkServiceGetTransactionsStreamOK) IsCode(code int) bool {
|
||||
return code == 200
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service get transactions stream o k response
|
||||
func (o *ArkServiceGetTransactionsStreamOK) Code() int {
|
||||
return 200
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOK) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /v1/transactions][%d] arkServiceGetTransactionsStreamOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOK) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /v1/transactions][%d] arkServiceGetTransactionsStreamOK %s", 200, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOK) GetPayload() *ArkServiceGetTransactionsStreamOKBody {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOK) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(ArkServiceGetTransactionsStreamOKBody)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewArkServiceGetTransactionsStreamDefault creates a ArkServiceGetTransactionsStreamDefault with default headers values
|
||||
func NewArkServiceGetTransactionsStreamDefault(code int) *ArkServiceGetTransactionsStreamDefault {
|
||||
return &ArkServiceGetTransactionsStreamDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetTransactionsStreamDefault describes a response with status code -1, with default header values.
|
||||
|
||||
An unexpected error response.
|
||||
*/
|
||||
type ArkServiceGetTransactionsStreamDefault struct {
|
||||
_statusCode int
|
||||
|
||||
Payload *models.RPCStatus
|
||||
}
|
||||
|
||||
// IsSuccess returns true when this ark service get transactions stream default response has a 2xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) IsSuccess() bool {
|
||||
return o._statusCode/100 == 2
|
||||
}
|
||||
|
||||
// IsRedirect returns true when this ark service get transactions stream default response has a 3xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) IsRedirect() bool {
|
||||
return o._statusCode/100 == 3
|
||||
}
|
||||
|
||||
// IsClientError returns true when this ark service get transactions stream default response has a 4xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) IsClientError() bool {
|
||||
return o._statusCode/100 == 4
|
||||
}
|
||||
|
||||
// IsServerError returns true when this ark service get transactions stream default response has a 5xx status code
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) IsServerError() bool {
|
||||
return o._statusCode/100 == 5
|
||||
}
|
||||
|
||||
// IsCode returns true when this ark service get transactions stream default response a status code equal to that given
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) IsCode(code int) bool {
|
||||
return o._statusCode == code
|
||||
}
|
||||
|
||||
// Code gets the status code for the ark service get transactions stream default response
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) Code() int {
|
||||
return o._statusCode
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) Error() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /v1/transactions][%d] ArkService_GetTransactionsStream default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) String() string {
|
||||
payload, _ := json.Marshal(o.Payload)
|
||||
return fmt.Sprintf("[GET /v1/transactions][%d] ArkService_GetTransactionsStream default %s", o._statusCode, payload)
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) GetPayload() *models.RPCStatus {
|
||||
return o.Payload
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamDefault) readResponse(response runtime.ClientResponse, consumer runtime.Consumer, formats strfmt.Registry) error {
|
||||
|
||||
o.Payload = new(models.RPCStatus)
|
||||
|
||||
// response payload
|
||||
if err := consumer.Consume(response.Body(), o.Payload); err != nil && err != io.EOF {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
ArkServiceGetTransactionsStreamOKBody Stream result of v1GetTransactionsStreamResponse
|
||||
swagger:model ArkServiceGetTransactionsStreamOKBody
|
||||
*/
|
||||
type ArkServiceGetTransactionsStreamOKBody struct {
|
||||
|
||||
// error
|
||||
Error *models.RPCStatus `json:"error,omitempty"`
|
||||
|
||||
// result
|
||||
Result *models.V1GetTransactionsStreamResponse `json:"result,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this ark service get transactions stream o k body
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := o.validateError(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := o.validateResult(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) validateError(formats strfmt.Registry) error {
|
||||
if swag.IsZero(o.Error) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if o.Error != nil {
|
||||
if err := o.Error.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "error")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "error")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) validateResult(formats strfmt.Registry) error {
|
||||
if swag.IsZero(o.Result) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if o.Result != nil {
|
||||
if err := o.Result.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "result")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "result")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this ark service get transactions stream o k body based on the context it is used
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := o.contextValidateError(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := o.contextValidateResult(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) contextValidateError(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if o.Error != nil {
|
||||
|
||||
if swag.IsZero(o.Error) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := o.Error.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "error")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "error")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) contextValidateResult(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if o.Result != nil {
|
||||
|
||||
if swag.IsZero(o.Result) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := o.Result.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "result")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("arkServiceGetTransactionsStreamOK" + "." + "result")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) MarshalBinary() ([]byte, error) {
|
||||
if o == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(o)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (o *ArkServiceGetTransactionsStreamOKBody) UnmarshalBinary(b []byte) error {
|
||||
var res ArkServiceGetTransactionsStreamOKBody
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*o = res
|
||||
return nil
|
||||
}
|
||||
@@ -19,9 +19,6 @@ type V1CompletePaymentRequest struct {
|
||||
|
||||
// signed redeem tx
|
||||
SignedRedeemTx string `json:"signedRedeemTx,omitempty"`
|
||||
|
||||
// signed unconditional forfeit txs
|
||||
SignedUnconditionalForfeitTxs []string `json:"signedUnconditionalForfeitTxs"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 complete payment request
|
||||
|
||||
@@ -19,9 +19,6 @@ type V1CreatePaymentResponse struct {
|
||||
|
||||
// signed only by the ASP
|
||||
SignedRedeemTx string `json:"signedRedeemTx,omitempty"`
|
||||
|
||||
// usigned unconditional forfeit txs
|
||||
UsignedUnconditionalForfeitTxs []string `json:"usignedUnconditionalForfeitTxs"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 create payment response
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1GetTransactionsStreamResponse v1 get transactions stream response
|
||||
//
|
||||
// swagger:model v1GetTransactionsStreamResponse
|
||||
type V1GetTransactionsStreamResponse struct {
|
||||
|
||||
// redeem
|
||||
Redeem *V1RedeemTransaction `json:"redeem,omitempty"`
|
||||
|
||||
// round
|
||||
Round *V1RoundTransaction `json:"round,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 get transactions stream response
|
||||
func (m *V1GetTransactionsStreamResponse) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateRedeem(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateRound(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1GetTransactionsStreamResponse) validateRedeem(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Redeem) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Redeem != nil {
|
||||
if err := m.Redeem.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("redeem")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("redeem")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1GetTransactionsStreamResponse) validateRound(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.Round) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.Round != nil {
|
||||
if err := m.Round.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("round")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("round")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 get transactions stream response based on the context it is used
|
||||
func (m *V1GetTransactionsStreamResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateRedeem(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateRound(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1GetTransactionsStreamResponse) contextValidateRedeem(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Redeem != nil {
|
||||
|
||||
if swag.IsZero(m.Redeem) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Redeem.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("redeem")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("redeem")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1GetTransactionsStreamResponse) contextValidateRound(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.Round != nil {
|
||||
|
||||
if swag.IsZero(m.Round) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.Round.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("round")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("round")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1GetTransactionsStreamResponse) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1GetTransactionsStreamResponse) UnmarshalBinary(b []byte) error {
|
||||
var res V1GetTransactionsStreamResponse
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -19,9 +19,6 @@ type V1PendingPayment struct {
|
||||
|
||||
// redeem tx
|
||||
RedeemTx string `json:"redeemTx,omitempty"`
|
||||
|
||||
// unconditional forfeit txs
|
||||
UnconditionalForfeitTxs []string `json:"unconditionalForfeitTxs"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 pending payment
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1RedeemTransaction v1 redeem transaction
|
||||
//
|
||||
// swagger:model v1RedeemTransaction
|
||||
type V1RedeemTransaction struct {
|
||||
|
||||
// spendable vtxos
|
||||
SpendableVtxos []*V1Vtxo `json:"spendableVtxos"`
|
||||
|
||||
// spent vtxos
|
||||
SpentVtxos []*V1Outpoint `json:"spentVtxos"`
|
||||
|
||||
// txid
|
||||
Txid string `json:"txid,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 redeem transaction
|
||||
func (m *V1RedeemTransaction) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateSpendableVtxos(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSpentVtxos(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RedeemTransaction) validateSpendableVtxos(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SpendableVtxos) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.SpendableVtxos); i++ {
|
||||
if swag.IsZero(m.SpendableVtxos[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.SpendableVtxos[i] != nil {
|
||||
if err := m.SpendableVtxos[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RedeemTransaction) validateSpentVtxos(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SpentVtxos) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.SpentVtxos); i++ {
|
||||
if swag.IsZero(m.SpentVtxos[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.SpentVtxos[i] != nil {
|
||||
if err := m.SpentVtxos[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 redeem transaction based on the context it is used
|
||||
func (m *V1RedeemTransaction) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateSpendableVtxos(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSpentVtxos(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RedeemTransaction) contextValidateSpendableVtxos(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.SpendableVtxos); i++ {
|
||||
|
||||
if m.SpendableVtxos[i] != nil {
|
||||
|
||||
if swag.IsZero(m.SpendableVtxos[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.SpendableVtxos[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RedeemTransaction) contextValidateSpentVtxos(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.SpentVtxos); i++ {
|
||||
|
||||
if m.SpentVtxos[i] != nil {
|
||||
|
||||
if swag.IsZero(m.SpentVtxos[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.SpentVtxos[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1RedeemTransaction) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1RedeemTransaction) UnmarshalBinary(b []byte) error {
|
||||
var res V1RedeemTransaction
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
package models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
)
|
||||
|
||||
// V1RoundTransaction v1 round transaction
|
||||
//
|
||||
// swagger:model v1RoundTransaction
|
||||
type V1RoundTransaction struct {
|
||||
|
||||
// claimed boarding utxos
|
||||
ClaimedBoardingUtxos []*V1Outpoint `json:"claimedBoardingUtxos"`
|
||||
|
||||
// spendable vtxos
|
||||
SpendableVtxos []*V1Vtxo `json:"spendableVtxos"`
|
||||
|
||||
// spent vtxos
|
||||
SpentVtxos []*V1Outpoint `json:"spentVtxos"`
|
||||
|
||||
// txid
|
||||
Txid string `json:"txid,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates this v1 round transaction
|
||||
func (m *V1RoundTransaction) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateClaimedBoardingUtxos(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSpendableVtxos(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateSpentVtxos(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) validateClaimedBoardingUtxos(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.ClaimedBoardingUtxos) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.ClaimedBoardingUtxos); i++ {
|
||||
if swag.IsZero(m.ClaimedBoardingUtxos[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.ClaimedBoardingUtxos[i] != nil {
|
||||
if err := m.ClaimedBoardingUtxos[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("claimedBoardingUtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("claimedBoardingUtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) validateSpendableVtxos(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SpendableVtxos) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.SpendableVtxos); i++ {
|
||||
if swag.IsZero(m.SpendableVtxos[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.SpendableVtxos[i] != nil {
|
||||
if err := m.SpendableVtxos[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) validateSpentVtxos(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.SpentVtxos) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
for i := 0; i < len(m.SpentVtxos); i++ {
|
||||
if swag.IsZero(m.SpentVtxos[i]) { // not required
|
||||
continue
|
||||
}
|
||||
|
||||
if m.SpentVtxos[i] != nil {
|
||||
if err := m.SpentVtxos[i].Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 round transaction based on the context it is used
|
||||
func (m *V1RoundTransaction) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.contextValidateClaimedBoardingUtxos(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSpendableVtxos(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidateSpentVtxos(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) contextValidateClaimedBoardingUtxos(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.ClaimedBoardingUtxos); i++ {
|
||||
|
||||
if m.ClaimedBoardingUtxos[i] != nil {
|
||||
|
||||
if swag.IsZero(m.ClaimedBoardingUtxos[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.ClaimedBoardingUtxos[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("claimedBoardingUtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("claimedBoardingUtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) contextValidateSpendableVtxos(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.SpendableVtxos); i++ {
|
||||
|
||||
if m.SpendableVtxos[i] != nil {
|
||||
|
||||
if swag.IsZero(m.SpendableVtxos[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.SpendableVtxos[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spendableVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1RoundTransaction) contextValidateSpentVtxos(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
for i := 0; i < len(m.SpentVtxos); i++ {
|
||||
|
||||
if m.SpentVtxos[i] != nil {
|
||||
|
||||
if swag.IsZero(m.SpentVtxos[i]) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.SpentVtxos[i].ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("spentVtxos" + "." + strconv.Itoa(i))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1RoundTransaction) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *V1RoundTransaction) UnmarshalBinary(b []byte) error {
|
||||
var res V1RoundTransaction
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
@@ -33,8 +33,8 @@ type V1Vtxo struct {
|
||||
// pending
|
||||
Pending bool `json:"pending,omitempty"`
|
||||
|
||||
// pending data
|
||||
PendingData *V1PendingPayment `json:"pendingData,omitempty"`
|
||||
// redeem tx
|
||||
RedeemTx string `json:"redeemTx,omitempty"`
|
||||
|
||||
// round txid
|
||||
RoundTxid string `json:"roundTxid,omitempty"`
|
||||
@@ -57,10 +57,6 @@ func (m *V1Vtxo) Validate(formats strfmt.Registry) error {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validatePendingData(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -86,25 +82,6 @@ func (m *V1Vtxo) validateOutpoint(formats strfmt.Registry) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1Vtxo) validatePendingData(formats strfmt.Registry) error {
|
||||
if swag.IsZero(m.PendingData) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if m.PendingData != nil {
|
||||
if err := m.PendingData.Validate(formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("pendingData")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("pendingData")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContextValidate validate this v1 vtxo based on the context it is used
|
||||
func (m *V1Vtxo) ContextValidate(ctx context.Context, formats strfmt.Registry) error {
|
||||
var res []error
|
||||
@@ -113,10 +90,6 @@ func (m *V1Vtxo) ContextValidate(ctx context.Context, formats strfmt.Registry) e
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.contextValidatePendingData(ctx, formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
@@ -144,27 +117,6 @@ func (m *V1Vtxo) contextValidateOutpoint(ctx context.Context, formats strfmt.Reg
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *V1Vtxo) contextValidatePendingData(ctx context.Context, formats strfmt.Registry) error {
|
||||
|
||||
if m.PendingData != nil {
|
||||
|
||||
if swag.IsZero(m.PendingData) { // not required
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := m.PendingData.ContextValidate(ctx, formats); err != nil {
|
||||
if ve, ok := err.(*errors.Validation); ok {
|
||||
return ve.ValidateName("pendingData")
|
||||
} else if ce, ok := err.(*errors.CompositeError); ok {
|
||||
return ce.ValidateName("pendingData")
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *V1Vtxo) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
|
||||
@@ -196,13 +196,12 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Txid: vtxo.Outpoint.Txid,
|
||||
VOut: vtxo.Outpoint.Vout,
|
||||
},
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
UnconditionalForfeitTxs: vtxo.PendingData.UnconditionalForfeitTxs,
|
||||
Pending: vtxo.Pending,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
Pending: vtxo.Pending,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,13 +220,12 @@ func loadFixtures(jsonStr string) (vtxos, map[string]struct{}, error) {
|
||||
Txid: vtxo.Outpoint.Txid,
|
||||
VOut: vtxo.Outpoint.Vout,
|
||||
},
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
UnconditionalForfeitTxs: vtxo.PendingData.UnconditionalForfeitTxs,
|
||||
Pending: vtxo.Pending,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
Amount: amount,
|
||||
RoundTxid: vtxo.PoolTxid,
|
||||
ExpiresAt: &expireAt,
|
||||
RedeemTx: vtxo.PendingData.RedeemTx,
|
||||
Pending: vtxo.Pending,
|
||||
SpentBy: vtxo.SpentBy,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -653,8 +653,7 @@ func (a *covenantlessArkClient) SendAsync(
|
||||
})
|
||||
}
|
||||
|
||||
redeemTx, unconditionalForfeitTxs, err := a.client.CreatePayment(
|
||||
ctx, inputs, receiversOutput)
|
||||
redeemTx, err := a.client.CreatePayment(ctx, inputs, receiversOutput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -667,7 +666,7 @@ func (a *covenantlessArkClient) SendAsync(
|
||||
}
|
||||
|
||||
if err = a.client.CompletePayment(
|
||||
ctx, signedRedeemTx, unconditionalForfeitTxs,
|
||||
ctx, signedRedeemTx,
|
||||
); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -320,12 +320,12 @@ func (s *covenantService) UpdatePaymentStatus(_ context.Context, id string) (dom
|
||||
return s.lastEvent, nil
|
||||
}
|
||||
|
||||
func (s *covenantService) CompleteAsyncPayment(ctx context.Context, redeemTx string, unconditionalForfeitTxs []string) error {
|
||||
func (s *covenantService) CompleteAsyncPayment(ctx context.Context, redeemTx string) error {
|
||||
return fmt.Errorf("unimplemented")
|
||||
}
|
||||
|
||||
func (s *covenantService) CreateAsyncPayment(ctx context.Context, inputs []ports.Input, receivers []domain.Receiver) (string, []string, error) {
|
||||
return "", nil, fmt.Errorf("unimplemented")
|
||||
func (s *covenantService) CreateAsyncPayment(ctx context.Context, inputs []ports.Input, receivers []domain.Receiver) (string, error) {
|
||||
return "", fmt.Errorf("unimplemented")
|
||||
}
|
||||
|
||||
func (s *covenantService) SignVtxos(ctx context.Context, forfeitTxs []string) error {
|
||||
|
||||
@@ -139,7 +139,7 @@ func (s *covenantlessService) Stop() {
|
||||
}
|
||||
|
||||
func (s *covenantlessService) CompleteAsyncPayment(
|
||||
ctx context.Context, redeemTx string, unconditionalForfeitTxs []string,
|
||||
ctx context.Context, redeemTx string,
|
||||
) error {
|
||||
redeemPtx, err := psbt.NewFromRawBytes(strings.NewReader(redeemTx), true)
|
||||
if err != nil {
|
||||
@@ -274,11 +274,8 @@ func (s *covenantlessService) CompleteAsyncPayment(
|
||||
Amount: uint64(out.Value),
|
||||
},
|
||||
ExpireAt: asyncPayData.expireAt,
|
||||
AsyncPayment: &domain.AsyncPaymentTxs{
|
||||
RedeemTx: redeemTx,
|
||||
UnconditionalForfeitTxs: unconditionalForfeitTxs,
|
||||
},
|
||||
Pending: isPending,
|
||||
RedeemTx: redeemTx,
|
||||
Pending: isPending,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -313,7 +310,7 @@ func (s *covenantlessService) CompleteAsyncPayment(
|
||||
|
||||
func (s *covenantlessService) CreateAsyncPayment(
|
||||
ctx context.Context, inputs []ports.Input, receivers []domain.Receiver,
|
||||
) (string, []string, error) {
|
||||
) (string, error) {
|
||||
vtxosKeys := make([]domain.VtxoKey, 0, len(inputs))
|
||||
for _, in := range inputs {
|
||||
vtxosKeys = append(vtxosKeys, in.VtxoKey)
|
||||
@@ -321,10 +318,10 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
|
||||
vtxos, err := s.repoManager.Vtxos().GetVtxos(ctx, vtxosKeys)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
return "", err
|
||||
}
|
||||
if len(vtxos) <= 0 {
|
||||
return "", nil, fmt.Errorf("vtxos not found")
|
||||
return "", fmt.Errorf("vtxos not found")
|
||||
}
|
||||
|
||||
vtxosInputs := make([]domain.Vtxo, 0, len(inputs))
|
||||
@@ -332,18 +329,18 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
expiration := vtxos[0].ExpireAt
|
||||
for _, vtxo := range vtxos {
|
||||
if vtxo.Spent {
|
||||
return "", nil, fmt.Errorf("all vtxos must be unspent")
|
||||
return "", fmt.Errorf("all vtxos must be unspent")
|
||||
}
|
||||
|
||||
if vtxo.Redeemed {
|
||||
return "", nil, fmt.Errorf("all vtxos must be redeemed")
|
||||
return "", fmt.Errorf("all vtxos must be redeemed")
|
||||
}
|
||||
|
||||
if vtxo.Swept {
|
||||
return "", nil, fmt.Errorf("all vtxos must be swept")
|
||||
return "", fmt.Errorf("all vtxos must be swept")
|
||||
}
|
||||
if vtxo.Pending {
|
||||
return "", nil, fmt.Errorf("all vtxos must be claimed")
|
||||
return "", fmt.Errorf("all vtxos must be claimed")
|
||||
}
|
||||
|
||||
if vtxo.ExpireAt < expiration {
|
||||
@@ -353,19 +350,19 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
vtxosInputs = append(vtxosInputs, vtxo)
|
||||
}
|
||||
|
||||
res, err := s.builder.BuildAsyncPaymentTransactions(
|
||||
redeemTx, err := s.builder.BuildAsyncPaymentTransactions(
|
||||
vtxosInputs, s.pubkey, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to build async payment txs: %s", err)
|
||||
return "", fmt.Errorf("failed to build async payment txs: %s", err)
|
||||
}
|
||||
|
||||
redeemTx, err := psbt.NewFromRawBytes(strings.NewReader(res.RedeemTx), true)
|
||||
redeemPtx, err := psbt.NewFromRawBytes(strings.NewReader(redeemTx), true)
|
||||
if err != nil {
|
||||
return "", nil, fmt.Errorf("failed to parse redeem tx: %s", err)
|
||||
return "", fmt.Errorf("failed to parse redeem tx: %s", err)
|
||||
}
|
||||
|
||||
s.asyncPaymentsCache[redeemTx.UnsignedTx.TxID()] = struct {
|
||||
s.asyncPaymentsCache[redeemPtx.UnsignedTx.TxID()] = struct {
|
||||
receivers []domain.Receiver
|
||||
expireAt int64
|
||||
}{
|
||||
@@ -373,7 +370,7 @@ func (s *covenantlessService) CreateAsyncPayment(
|
||||
expireAt: expiration,
|
||||
}
|
||||
|
||||
return res.RedeemTx, res.UnconditionalForfeitTxs, nil
|
||||
return redeemTx, nil
|
||||
}
|
||||
|
||||
func (s *covenantlessService) GetBoardingAddress(
|
||||
@@ -1536,7 +1533,7 @@ func (s *covenantlessService) reactToFraud(ctx context.Context, vtxo domain.Vtxo
|
||||
|
||||
log.Debugf("vtxo %s:%d has been spent by async payment", vtxo.Txid, vtxo.VOut)
|
||||
|
||||
redeemTxHex, err := s.builder.FinalizeAndExtract(asyncPayVtxo.AsyncPayment.RedeemTx)
|
||||
redeemTxHex, err := s.builder.FinalizeAndExtract(asyncPayVtxo.RedeemTx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to finalize redeem tx: %s", err)
|
||||
}
|
||||
|
||||
@@ -33,9 +33,9 @@ type Service interface {
|
||||
// Async payments
|
||||
CreateAsyncPayment(
|
||||
ctx context.Context, inputs []ports.Input, receivers []domain.Receiver,
|
||||
) (string, []string, error)
|
||||
) (string, error)
|
||||
CompleteAsyncPayment(
|
||||
ctx context.Context, redeemTx string, unconditionalForfeitTxs []string,
|
||||
ctx context.Context, redeemTx string,
|
||||
) error
|
||||
GetBoardingAddress(
|
||||
ctx context.Context, userPubkey *secp256k1.PublicKey,
|
||||
|
||||
@@ -108,17 +108,12 @@ func (r Receiver) IsOnchain() bool {
|
||||
type Vtxo struct {
|
||||
VtxoKey
|
||||
Receiver
|
||||
RoundTxid string
|
||||
SpentBy string // round txid or async redeem txid
|
||||
Spent bool
|
||||
Redeemed bool
|
||||
Swept bool
|
||||
ExpireAt int64
|
||||
AsyncPayment *AsyncPaymentTxs // nil if not async vtxo
|
||||
Pending bool
|
||||
}
|
||||
|
||||
type AsyncPaymentTxs struct {
|
||||
RedeemTx string // always signed by the ASP when created
|
||||
UnconditionalForfeitTxs []string
|
||||
RoundTxid string
|
||||
SpentBy string // round txid or async redeem txid
|
||||
Spent bool
|
||||
Redeemed bool
|
||||
Swept bool
|
||||
ExpireAt int64
|
||||
RedeemTx string // empty if in-round vtxo
|
||||
Pending bool
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ type TxBuilder interface {
|
||||
BuildAsyncPaymentTransactions(
|
||||
vtxosToSpend []domain.Vtxo,
|
||||
aspPubKey *secp256k1.PublicKey, receivers []domain.Receiver,
|
||||
) (*domain.AsyncPaymentTxs, error)
|
||||
) (string, error)
|
||||
VerifyAndCombinePartialTx(dest string, src string) (string, error)
|
||||
GetTxID(tx string) (string, error)
|
||||
}
|
||||
|
||||
@@ -41,15 +41,6 @@ CREATE TABLE IF NOT EXISTS tx (
|
||||
FOREIGN KEY (round_id) REFERENCES round(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS uncond_forfeit_tx (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
tx TEXT NOT NULL,
|
||||
vtxo_txid TEXT NOT NULL,
|
||||
vtxo_vout INTEGER NOT NULL,
|
||||
position INTEGER NOT NULL,
|
||||
FOREIGN KEY (vtxo_txid, vtxo_vout) REFERENCES vtxo(txid, vout)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vtxo (
|
||||
txid TEXT NOT NULL,
|
||||
vout INTEGER NOT NULL,
|
||||
@@ -85,9 +76,4 @@ ON payment.id=receiver.payment_id;
|
||||
CREATE VIEW payment_vtxo_vw AS SELECT vtxo.*
|
||||
FROM payment
|
||||
LEFT OUTER JOIN vtxo
|
||||
ON payment.id=vtxo.payment_id;
|
||||
|
||||
CREATE VIEW uncond_forfeit_tx_vw AS SELECT uncond_forfeit_tx.*
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx
|
||||
ON vtxo.txid=uncond_forfeit_tx.vtxo_txid AND vtxo.vout=uncond_forfeit_tx.vtxo_vout;
|
||||
ON payment.id=vtxo.payment_id;
|
||||
@@ -87,22 +87,6 @@ type Tx struct {
|
||||
IsLeaf sql.NullBool
|
||||
}
|
||||
|
||||
type UncondForfeitTx struct {
|
||||
ID int64
|
||||
Tx string
|
||||
VtxoTxid string
|
||||
VtxoVout int64
|
||||
Position int64
|
||||
}
|
||||
|
||||
type UncondForfeitTxVw struct {
|
||||
ID sql.NullInt64
|
||||
Tx sql.NullString
|
||||
VtxoTxid sql.NullString
|
||||
VtxoVout sql.NullInt64
|
||||
Position sql.NullInt64
|
||||
}
|
||||
|
||||
type Vtxo struct {
|
||||
Txid string
|
||||
Vout int64
|
||||
|
||||
@@ -54,16 +54,12 @@ func (q *Queries) MarkVtxoAsSwept(ctx context.Context, arg MarkVtxoAsSweptParams
|
||||
}
|
||||
|
||||
const selectNotRedeemedVtxos = `-- name: SelectNotRedeemedVtxos :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending,
|
||||
uncond_forfeit_tx_vw.id, uncond_forfeit_tx_vw.tx, uncond_forfeit_tx_vw.vtxo_txid, uncond_forfeit_tx_vw.vtxo_vout, uncond_forfeit_tx_vw.position
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending FROM vtxo
|
||||
WHERE redeemed = false
|
||||
`
|
||||
|
||||
type SelectNotRedeemedVtxosRow struct {
|
||||
Vtxo Vtxo
|
||||
UncondForfeitTxVw UncondForfeitTxVw
|
||||
Vtxo Vtxo
|
||||
}
|
||||
|
||||
func (q *Queries) SelectNotRedeemedVtxos(ctx context.Context) ([]SelectNotRedeemedVtxosRow, error) {
|
||||
@@ -89,11 +85,6 @@ func (q *Queries) SelectNotRedeemedVtxos(ctx context.Context) ([]SelectNotRedeem
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Descriptor,
|
||||
&i.Vtxo.Pending,
|
||||
&i.UncondForfeitTxVw.ID,
|
||||
&i.UncondForfeitTxVw.Tx,
|
||||
&i.UncondForfeitTxVw.VtxoTxid,
|
||||
&i.UncondForfeitTxVw.VtxoVout,
|
||||
&i.UncondForfeitTxVw.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,16 +100,12 @@ func (q *Queries) SelectNotRedeemedVtxos(ctx context.Context) ([]SelectNotRedeem
|
||||
}
|
||||
|
||||
const selectNotRedeemedVtxosWithPubkey = `-- name: SelectNotRedeemedVtxosWithPubkey :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending,
|
||||
uncond_forfeit_tx_vw.id, uncond_forfeit_tx_vw.tx, uncond_forfeit_tx_vw.vtxo_txid, uncond_forfeit_tx_vw.vtxo_vout, uncond_forfeit_tx_vw.position
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending FROM vtxo
|
||||
WHERE redeemed = false AND INSTR(descriptor, ?) > 0
|
||||
`
|
||||
|
||||
type SelectNotRedeemedVtxosWithPubkeyRow struct {
|
||||
Vtxo Vtxo
|
||||
UncondForfeitTxVw UncondForfeitTxVw
|
||||
Vtxo Vtxo
|
||||
}
|
||||
|
||||
func (q *Queries) SelectNotRedeemedVtxosWithPubkey(ctx context.Context, instr string) ([]SelectNotRedeemedVtxosWithPubkeyRow, error) {
|
||||
@@ -144,11 +131,6 @@ func (q *Queries) SelectNotRedeemedVtxosWithPubkey(ctx context.Context, instr st
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Descriptor,
|
||||
&i.Vtxo.Pending,
|
||||
&i.UncondForfeitTxVw.ID,
|
||||
&i.UncondForfeitTxVw.Tx,
|
||||
&i.UncondForfeitTxVw.VtxoTxid,
|
||||
&i.UncondForfeitTxVw.VtxoVout,
|
||||
&i.UncondForfeitTxVw.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -481,16 +463,12 @@ func (q *Queries) SelectSweepableRounds(ctx context.Context) ([]SelectSweepableR
|
||||
}
|
||||
|
||||
const selectSweepableVtxos = `-- name: SelectSweepableVtxos :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending,
|
||||
uncond_forfeit_tx_vw.id, uncond_forfeit_tx_vw.tx, uncond_forfeit_tx_vw.vtxo_txid, uncond_forfeit_tx_vw.vtxo_vout, uncond_forfeit_tx_vw.position
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending FROM vtxo
|
||||
WHERE redeemed = false AND swept = false
|
||||
`
|
||||
|
||||
type SelectSweepableVtxosRow struct {
|
||||
Vtxo Vtxo
|
||||
UncondForfeitTxVw UncondForfeitTxVw
|
||||
Vtxo Vtxo
|
||||
}
|
||||
|
||||
func (q *Queries) SelectSweepableVtxos(ctx context.Context) ([]SelectSweepableVtxosRow, error) {
|
||||
@@ -516,11 +494,6 @@ func (q *Queries) SelectSweepableVtxos(ctx context.Context) ([]SelectSweepableVt
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Descriptor,
|
||||
&i.Vtxo.Pending,
|
||||
&i.UncondForfeitTxVw.ID,
|
||||
&i.UncondForfeitTxVw.Tx,
|
||||
&i.UncondForfeitTxVw.VtxoTxid,
|
||||
&i.UncondForfeitTxVw.VtxoVout,
|
||||
&i.UncondForfeitTxVw.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -622,10 +595,7 @@ func (q *Queries) SelectSweptRounds(ctx context.Context) ([]SelectSweptRoundsRow
|
||||
}
|
||||
|
||||
const selectVtxoByOutpoint = `-- name: SelectVtxoByOutpoint :one
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending,
|
||||
uncond_forfeit_tx_vw.id, uncond_forfeit_tx_vw.tx, uncond_forfeit_tx_vw.vtxo_txid, uncond_forfeit_tx_vw.vtxo_vout, uncond_forfeit_tx_vw.position
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending FROM vtxo
|
||||
WHERE txid = ? AND vout = ?
|
||||
`
|
||||
|
||||
@@ -635,8 +605,7 @@ type SelectVtxoByOutpointParams struct {
|
||||
}
|
||||
|
||||
type SelectVtxoByOutpointRow struct {
|
||||
Vtxo Vtxo
|
||||
UncondForfeitTxVw UncondForfeitTxVw
|
||||
Vtxo Vtxo
|
||||
}
|
||||
|
||||
func (q *Queries) SelectVtxoByOutpoint(ctx context.Context, arg SelectVtxoByOutpointParams) (SelectVtxoByOutpointRow, error) {
|
||||
@@ -656,26 +625,17 @@ func (q *Queries) SelectVtxoByOutpoint(ctx context.Context, arg SelectVtxoByOutp
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Descriptor,
|
||||
&i.Vtxo.Pending,
|
||||
&i.UncondForfeitTxVw.ID,
|
||||
&i.UncondForfeitTxVw.Tx,
|
||||
&i.UncondForfeitTxVw.VtxoTxid,
|
||||
&i.UncondForfeitTxVw.VtxoVout,
|
||||
&i.UncondForfeitTxVw.Position,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const selectVtxosByPoolTxid = `-- name: SelectVtxosByPoolTxid :many
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending,
|
||||
uncond_forfeit_tx_vw.id, uncond_forfeit_tx_vw.tx, uncond_forfeit_tx_vw.vtxo_txid, uncond_forfeit_tx_vw.vtxo_vout, uncond_forfeit_tx_vw.position
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT vtxo.txid, vtxo.vout, vtxo.amount, vtxo.pool_tx, vtxo.spent_by, vtxo.spent, vtxo.redeemed, vtxo.swept, vtxo.expire_at, vtxo.payment_id, vtxo.redeem_tx, vtxo.descriptor, vtxo.pending FROM vtxo
|
||||
WHERE pool_tx = ?
|
||||
`
|
||||
|
||||
type SelectVtxosByPoolTxidRow struct {
|
||||
Vtxo Vtxo
|
||||
UncondForfeitTxVw UncondForfeitTxVw
|
||||
Vtxo Vtxo
|
||||
}
|
||||
|
||||
func (q *Queries) SelectVtxosByPoolTxid(ctx context.Context, poolTx string) ([]SelectVtxosByPoolTxidRow, error) {
|
||||
@@ -701,11 +661,6 @@ func (q *Queries) SelectVtxosByPoolTxid(ctx context.Context, poolTx string) ([]S
|
||||
&i.Vtxo.RedeemTx,
|
||||
&i.Vtxo.Descriptor,
|
||||
&i.Vtxo.Pending,
|
||||
&i.UncondForfeitTxVw.ID,
|
||||
&i.UncondForfeitTxVw.Tx,
|
||||
&i.UncondForfeitTxVw.VtxoTxid,
|
||||
&i.UncondForfeitTxVw.VtxoVout,
|
||||
&i.UncondForfeitTxVw.Position,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -891,32 +846,6 @@ func (q *Queries) UpsertTransaction(ctx context.Context, arg UpsertTransactionPa
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertUnconditionalForfeitTx = `-- name: UpsertUnconditionalForfeitTx :exec
|
||||
INSERT INTO uncond_forfeit_tx (tx, vtxo_txid, vtxo_vout, position)
|
||||
VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET
|
||||
tx = EXCLUDED.tx,
|
||||
vtxo_txid = EXCLUDED.vtxo_txid,
|
||||
vtxo_vout = EXCLUDED.vtxo_vout,
|
||||
position = EXCLUDED.position
|
||||
`
|
||||
|
||||
type UpsertUnconditionalForfeitTxParams struct {
|
||||
Tx string
|
||||
VtxoTxid string
|
||||
VtxoVout int64
|
||||
Position int64
|
||||
}
|
||||
|
||||
func (q *Queries) UpsertUnconditionalForfeitTx(ctx context.Context, arg UpsertUnconditionalForfeitTxParams) error {
|
||||
_, err := q.db.ExecContext(ctx, upsertUnconditionalForfeitTx,
|
||||
arg.Tx,
|
||||
arg.VtxoTxid,
|
||||
arg.VtxoVout,
|
||||
arg.Position,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertVtxo = `-- name: UpsertVtxo :exec
|
||||
INSERT INTO vtxo (txid, vout, descriptor, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx, pending)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
|
||||
@@ -111,14 +111,6 @@ SELECT id FROM round WHERE starting_timestamp > ? AND starting_timestamp < ?;
|
||||
-- name: SelectRoundIds :many
|
||||
SELECT id FROM round;
|
||||
|
||||
-- name: UpsertUnconditionalForfeitTx :exec
|
||||
INSERT INTO uncond_forfeit_tx (tx, vtxo_txid, vtxo_vout, position)
|
||||
VALUES (?, ?, ?, ?) ON CONFLICT(id) DO UPDATE SET
|
||||
tx = EXCLUDED.tx,
|
||||
vtxo_txid = EXCLUDED.vtxo_txid,
|
||||
vtxo_vout = EXCLUDED.vtxo_vout,
|
||||
position = EXCLUDED.position;
|
||||
|
||||
-- name: UpsertVtxo :exec
|
||||
INSERT INTO vtxo (txid, vout, descriptor, amount, pool_tx, spent_by, spent, redeemed, swept, expire_at, redeem_tx, pending)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SET
|
||||
@@ -134,38 +126,23 @@ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(txid, vout) DO UPDATE SE
|
||||
pending = EXCLUDED.pending;
|
||||
|
||||
-- name: SelectSweepableVtxos :many
|
||||
SELECT sqlc.embed(vtxo),
|
||||
sqlc.embed(uncond_forfeit_tx_vw)
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
WHERE redeemed = false AND swept = false;
|
||||
|
||||
-- name: SelectNotRedeemedVtxos :many
|
||||
SELECT sqlc.embed(vtxo),
|
||||
sqlc.embed(uncond_forfeit_tx_vw)
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
WHERE redeemed = false;
|
||||
|
||||
-- name: SelectNotRedeemedVtxosWithPubkey :many
|
||||
SELECT sqlc.embed(vtxo),
|
||||
sqlc.embed(uncond_forfeit_tx_vw)
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
WHERE redeemed = false AND INSTR(descriptor, ?) > 0;
|
||||
|
||||
-- name: SelectVtxoByOutpoint :one
|
||||
SELECT sqlc.embed(vtxo),
|
||||
sqlc.embed(uncond_forfeit_tx_vw)
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
WHERE txid = ? AND vout = ?;
|
||||
|
||||
-- name: SelectVtxosByPoolTxid :many
|
||||
SELECT sqlc.embed(vtxo),
|
||||
sqlc.embed(uncond_forfeit_tx_vw)
|
||||
FROM vtxo
|
||||
LEFT OUTER JOIN uncond_forfeit_tx_vw ON vtxo.txid=uncond_forfeit_tx_vw.vtxo_txid AND vtxo.vout=uncond_forfeit_tx_vw.vtxo_vout
|
||||
SELECT sqlc.embed(vtxo) FROM vtxo
|
||||
WHERE pool_tx = ?;
|
||||
|
||||
-- name: MarkVtxoAsRedeemed :exec
|
||||
|
||||
@@ -37,10 +37,6 @@ func (v *vxtoRepository) AddVtxos(ctx context.Context, vtxos []domain.Vtxo) erro
|
||||
txBody := func(querierWithTx *queries.Queries) error {
|
||||
for i := range vtxos {
|
||||
vtxo := vtxos[i]
|
||||
var redeemTx string
|
||||
if vtxo.AsyncPayment != nil {
|
||||
redeemTx = vtxo.AsyncPayment.RedeemTx
|
||||
}
|
||||
if err := querierWithTx.UpsertVtxo(
|
||||
ctx, queries.UpsertVtxoParams{
|
||||
Txid: vtxo.Txid,
|
||||
@@ -53,25 +49,12 @@ func (v *vxtoRepository) AddVtxos(ctx context.Context, vtxos []domain.Vtxo) erro
|
||||
Redeemed: vtxo.Redeemed,
|
||||
Swept: vtxo.Swept,
|
||||
ExpireAt: vtxo.ExpireAt,
|
||||
RedeemTx: sql.NullString{String: redeemTx, Valid: true},
|
||||
RedeemTx: sql.NullString{String: vtxo.RedeemTx, Valid: true},
|
||||
Pending: vtxo.Pending,
|
||||
},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if vtxo.AsyncPayment != nil {
|
||||
for i, tx := range vtxo.AsyncPayment.UnconditionalForfeitTxs {
|
||||
if err := querierWithTx.UpsertUnconditionalForfeitTx(ctx, queries.UpsertUnconditionalForfeitTxParams{
|
||||
Tx: tx,
|
||||
VtxoTxid: vtxo.Txid,
|
||||
VtxoVout: int64(vtxo.VOut),
|
||||
Position: int64(i),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -86,12 +69,9 @@ func (v *vxtoRepository) GetAllSweepableVtxos(ctx context.Context) ([]domain.Vtx
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows := make([]vtxoWithUnconditionalForfeitTxs, 0, len(res))
|
||||
rows := make([]queries.Vtxo, 0, len(res))
|
||||
for _, row := range res {
|
||||
rows = append(rows, vtxoWithUnconditionalForfeitTxs{
|
||||
vtxo: row.Vtxo,
|
||||
tx: row.UncondForfeitTxVw,
|
||||
})
|
||||
rows = append(rows, row.Vtxo)
|
||||
}
|
||||
return readRows(rows)
|
||||
}
|
||||
@@ -99,7 +79,7 @@ func (v *vxtoRepository) GetAllSweepableVtxos(ctx context.Context) ([]domain.Vtx
|
||||
func (v *vxtoRepository) GetAllVtxos(ctx context.Context, pubkey string) ([]domain.Vtxo, []domain.Vtxo, error) {
|
||||
withPubkey := len(pubkey) > 0
|
||||
|
||||
var rows []vtxoWithUnconditionalForfeitTxs
|
||||
var rows []queries.Vtxo
|
||||
if withPubkey {
|
||||
if len(pubkey) == 66 {
|
||||
pubkey = pubkey[2:]
|
||||
@@ -109,24 +89,18 @@ func (v *vxtoRepository) GetAllVtxos(ctx context.Context, pubkey string) ([]doma
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
rows = make([]vtxoWithUnconditionalForfeitTxs, 0, len(res))
|
||||
rows = make([]queries.Vtxo, 0, len(res))
|
||||
for _, row := range res {
|
||||
rows = append(rows, vtxoWithUnconditionalForfeitTxs{
|
||||
vtxo: row.Vtxo,
|
||||
tx: row.UncondForfeitTxVw,
|
||||
})
|
||||
rows = append(rows, row.Vtxo)
|
||||
}
|
||||
} else {
|
||||
res, err := v.querier.SelectNotRedeemedVtxos(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
rows = make([]vtxoWithUnconditionalForfeitTxs, 0, len(res))
|
||||
rows = make([]queries.Vtxo, 0, len(res))
|
||||
for _, row := range res {
|
||||
rows = append(rows, vtxoWithUnconditionalForfeitTxs{
|
||||
vtxo: row.Vtxo,
|
||||
tx: row.UncondForfeitTxVw,
|
||||
})
|
||||
rows = append(rows, row.Vtxo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,12 +137,7 @@ func (v *vxtoRepository) GetVtxos(ctx context.Context, outpoints []domain.VtxoKe
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := readRows([]vtxoWithUnconditionalForfeitTxs{
|
||||
{
|
||||
vtxo: res.Vtxo,
|
||||
tx: res.UncondForfeitTxVw,
|
||||
},
|
||||
})
|
||||
result, err := readRows([]queries.Vtxo{res.Vtxo})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,12 +157,9 @@ func (v *vxtoRepository) GetVtxosForRound(ctx context.Context, txid string) ([]d
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows := make([]vtxoWithUnconditionalForfeitTxs, 0, len(res))
|
||||
rows := make([]queries.Vtxo, 0, len(res))
|
||||
for _, row := range res {
|
||||
rows = append(rows, vtxoWithUnconditionalForfeitTxs{
|
||||
vtxo: row.Vtxo,
|
||||
tx: row.UncondForfeitTxVw,
|
||||
})
|
||||
rows = append(rows, row.Vtxo)
|
||||
}
|
||||
|
||||
return readRows(rows)
|
||||
@@ -281,18 +247,7 @@ func (v *vxtoRepository) UpdateExpireAt(ctx context.Context, vtxos []domain.Vtxo
|
||||
return execTx(ctx, v.db, txBody)
|
||||
}
|
||||
|
||||
func rowToVtxo(row queries.Vtxo, uncondForfeitTxs []queries.UncondForfeitTxVw) domain.Vtxo {
|
||||
var asyncPayment *domain.AsyncPaymentTxs
|
||||
if row.RedeemTx.Valid && len(uncondForfeitTxs) > 0 {
|
||||
txs := make([]string, len(uncondForfeitTxs))
|
||||
for _, tx := range uncondForfeitTxs {
|
||||
txs[tx.Position.Int64] = tx.Tx.String
|
||||
}
|
||||
asyncPayment = &domain.AsyncPaymentTxs{
|
||||
RedeemTx: row.RedeemTx.String,
|
||||
UnconditionalForfeitTxs: txs,
|
||||
}
|
||||
}
|
||||
func rowToVtxo(row queries.Vtxo) domain.Vtxo {
|
||||
return domain.Vtxo{
|
||||
VtxoKey: domain.VtxoKey{
|
||||
Txid: row.Txid,
|
||||
@@ -302,49 +257,21 @@ func rowToVtxo(row queries.Vtxo, uncondForfeitTxs []queries.UncondForfeitTxVw) d
|
||||
Descriptor: row.Descriptor.String,
|
||||
Amount: uint64(row.Amount),
|
||||
},
|
||||
RoundTxid: row.PoolTx,
|
||||
SpentBy: row.SpentBy,
|
||||
Spent: row.Spent,
|
||||
Redeemed: row.Redeemed,
|
||||
Swept: row.Swept,
|
||||
ExpireAt: row.ExpireAt,
|
||||
AsyncPayment: asyncPayment,
|
||||
Pending: row.Pending,
|
||||
RoundTxid: row.PoolTx,
|
||||
SpentBy: row.SpentBy,
|
||||
Spent: row.Spent,
|
||||
Redeemed: row.Redeemed,
|
||||
Swept: row.Swept,
|
||||
ExpireAt: row.ExpireAt,
|
||||
RedeemTx: row.RedeemTx.String,
|
||||
Pending: row.Pending,
|
||||
}
|
||||
}
|
||||
|
||||
type vtxoWithUnconditionalForfeitTxs struct {
|
||||
vtxo queries.Vtxo
|
||||
tx queries.UncondForfeitTxVw
|
||||
}
|
||||
|
||||
func readRows(rows []vtxoWithUnconditionalForfeitTxs) ([]domain.Vtxo, error) {
|
||||
uncondForfeitTxsMap := make(map[domain.VtxoKey][]queries.UncondForfeitTxVw)
|
||||
for _, row := range rows {
|
||||
if !row.vtxo.RedeemTx.Valid {
|
||||
continue
|
||||
}
|
||||
vtxoKey := domain.VtxoKey{
|
||||
Txid: row.vtxo.Txid,
|
||||
VOut: uint32(row.vtxo.Vout),
|
||||
}
|
||||
if _, ok := uncondForfeitTxsMap[vtxoKey]; !ok {
|
||||
uncondForfeitTxsMap[vtxoKey] = make([]queries.UncondForfeitTxVw, 0)
|
||||
}
|
||||
if row.tx.Tx.Valid {
|
||||
uncondForfeitTxsMap[vtxoKey] = append(
|
||||
uncondForfeitTxsMap[vtxoKey], row.tx,
|
||||
)
|
||||
}
|
||||
}
|
||||
func readRows(rows []queries.Vtxo) ([]domain.Vtxo, error) {
|
||||
vtxos := make([]domain.Vtxo, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
vtxoKey := domain.VtxoKey{
|
||||
Txid: row.vtxo.Txid,
|
||||
VOut: uint32(row.vtxo.Vout),
|
||||
}
|
||||
uncondForfeitTxs := uncondForfeitTxsMap[vtxoKey]
|
||||
vtxos = append(vtxos, rowToVtxo(row.vtxo, uncondForfeitTxs))
|
||||
for _, vtxo := range rows {
|
||||
vtxos = append(vtxos, rowToVtxo(vtxo))
|
||||
}
|
||||
|
||||
return vtxos, nil
|
||||
|
||||
@@ -365,8 +365,8 @@ func (b *txBuilder) FindLeaves(
|
||||
|
||||
func (b *txBuilder) BuildAsyncPaymentTransactions(
|
||||
_ []domain.Vtxo, _ *secp256k1.PublicKey, _ []domain.Receiver,
|
||||
) (*domain.AsyncPaymentTxs, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
) (string, error) {
|
||||
return "", fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (b *txBuilder) createPoolTx(
|
||||
|
||||
@@ -402,28 +402,25 @@ func (b *txBuilder) FindLeaves(congestionTree tree.CongestionTree, fromtxid stri
|
||||
|
||||
func (b *txBuilder) BuildAsyncPaymentTransactions(
|
||||
vtxos []domain.Vtxo, aspPubKey *secp256k1.PublicKey, receivers []domain.Receiver,
|
||||
) (*domain.AsyncPaymentTxs, error) {
|
||||
) (string, error) {
|
||||
if len(vtxos) <= 0 {
|
||||
return nil, fmt.Errorf("missing vtxos")
|
||||
return "", fmt.Errorf("missing vtxos")
|
||||
}
|
||||
|
||||
ins := make([]*wire.OutPoint, 0, len(vtxos))
|
||||
outs := make([]*wire.TxOut, 0, len(receivers))
|
||||
unconditionalForfeitTxs := make([]string, 0, len(vtxos))
|
||||
redeemTxWeightEstimator := &input.TxWeightEstimator{}
|
||||
for _, vtxo := range vtxos {
|
||||
if vtxo.Spent || vtxo.Redeemed || vtxo.Swept {
|
||||
return nil, fmt.Errorf("all vtxos must be unspent")
|
||||
}
|
||||
witnessUtxos := make(map[int]*wire.TxOut)
|
||||
tapscripts := make(map[int]*psbt.TaprootTapLeafScript)
|
||||
|
||||
aspScript, err := common.P2TRScript(aspPubKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
redeemTxWeightEstimator := &input.TxWeightEstimator{}
|
||||
for index, vtxo := range vtxos {
|
||||
if vtxo.Spent || vtxo.Redeemed || vtxo.Swept {
|
||||
return "", fmt.Errorf("all vtxos must be unspent")
|
||||
}
|
||||
|
||||
vtxoTxID, err := chainhash.NewHashFromStr(vtxo.Txid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
vtxoOutpoint := &wire.OutPoint{
|
||||
@@ -433,104 +430,60 @@ func (b *txBuilder) BuildAsyncPaymentTransactions(
|
||||
|
||||
vtxoScript, err := bitcointree.ParseVtxoScript(vtxo.Descriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
vtxoTapKey, vtxoTree, err := vtxoScript.TapTree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
vtxoOutputScript, err := common.P2TRScript(vtxoTapKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
var tapscript *waddrmgr.Tapscript
|
||||
forfeitTxWeightEstimator := &input.TxWeightEstimator{}
|
||||
|
||||
if defaultVtxoScript, ok := vtxoScript.(*bitcointree.DefaultVtxoScript); ok {
|
||||
forfeitClosure := &bitcointree.MultisigClosure{
|
||||
Pubkey: defaultVtxoScript.Owner,
|
||||
AspPubkey: defaultVtxoScript.Asp,
|
||||
}
|
||||
|
||||
forfeitLeaf, err := forfeitClosure.Leaf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
forfeitProof, err := vtxoTree.GetTaprootMerkleProof(forfeitLeaf.TapHash())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ctrlBlock, err := txscript.ParseControlBlock(forfeitProof.ControlBlock)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tapscript = &waddrmgr.Tapscript{
|
||||
RevealedScript: forfeitProof.Script,
|
||||
ControlBlock: ctrlBlock,
|
||||
}
|
||||
forfeitTxWeightEstimator.AddTapscriptInput(64*2, tapscript)
|
||||
forfeitTxWeightEstimator.AddP2TROutput() // ASP output
|
||||
} else {
|
||||
return nil, fmt.Errorf("vtxo script is not a default vtxo script, cannot be async spent")
|
||||
}
|
||||
|
||||
forfeitTxFee, err := b.wallet.MinRelayFee(context.Background(), uint64(forfeitTxWeightEstimator.VSize()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if forfeitTxFee >= vtxo.Amount {
|
||||
return nil, fmt.Errorf("forfeit tx fee is higher than the amount of the vtxo")
|
||||
}
|
||||
|
||||
output := &wire.TxOut{
|
||||
PkScript: aspScript,
|
||||
Value: int64(vtxo.Amount - forfeitTxFee),
|
||||
}
|
||||
|
||||
unconditionnalForfeitPtx, err := psbt.New(
|
||||
[]*wire.OutPoint{vtxoOutpoint},
|
||||
[]*wire.TxOut{output},
|
||||
2,
|
||||
0,
|
||||
[]uint32{wire.MaxTxInSequenceNum},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unconditionnalForfeitPtx.Inputs[0].WitnessUtxo = &wire.TxOut{
|
||||
witnessUtxos[index] = &wire.TxOut{
|
||||
Value: int64(vtxo.Amount),
|
||||
PkScript: vtxoOutputScript,
|
||||
}
|
||||
|
||||
ctrlBlock, err := tapscript.ControlBlock.ToBytes()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if defaultVtxoScript, ok := vtxoScript.(*bitcointree.DefaultVtxoScript); ok {
|
||||
forfeitLeaf := bitcointree.MultisigClosure{
|
||||
Pubkey: defaultVtxoScript.Owner,
|
||||
AspPubkey: defaultVtxoScript.Asp,
|
||||
}
|
||||
|
||||
unconditionnalForfeitPtx.Inputs[0].TaprootLeafScript = []*psbt.TaprootTapLeafScript{
|
||||
{
|
||||
Script: tapscript.RevealedScript,
|
||||
ControlBlock: ctrlBlock,
|
||||
tapLeaf, err := forfeitLeaf.Leaf()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
leafProof, err := vtxoTree.GetTaprootMerkleProof(tapLeaf.TapHash())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
tapscripts[index] = &psbt.TaprootTapLeafScript{
|
||||
ControlBlock: leafProof.ControlBlock,
|
||||
Script: leafProof.Script,
|
||||
LeafVersion: txscript.BaseLeafVersion,
|
||||
},
|
||||
}
|
||||
|
||||
ctrlBlock, err := txscript.ParseControlBlock(leafProof.ControlBlock)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
redeemTxWeightEstimator.AddTapscriptInput(64*2, &waddrmgr.Tapscript{
|
||||
RevealedScript: leafProof.Script,
|
||||
ControlBlock: ctrlBlock,
|
||||
})
|
||||
} else {
|
||||
return "", fmt.Errorf("vtxo %s:%d script is not default script, can't be async spent", vtxo.Txid, vtxo.VOut)
|
||||
}
|
||||
|
||||
forfeitTx, err := unconditionnalForfeitPtx.B64Encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
unconditionalForfeitTxs = append(unconditionalForfeitTxs, forfeitTx)
|
||||
ins = append(ins, vtxoOutpoint)
|
||||
redeemTxWeightEstimator.AddTapscriptInput(64*2, tapscript)
|
||||
}
|
||||
|
||||
for range receivers {
|
||||
@@ -539,27 +492,27 @@ func (b *txBuilder) BuildAsyncPaymentTransactions(
|
||||
|
||||
redeemTxMinRelayFee, err := b.wallet.MinRelayFee(context.Background(), uint64(redeemTxWeightEstimator.VSize()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if redeemTxMinRelayFee >= receivers[len(receivers)-1].Amount {
|
||||
return nil, fmt.Errorf("redeem tx fee is higher than the amount of the change receiver")
|
||||
return "", fmt.Errorf("redeem tx fee is higher than the amount of the change receiver")
|
||||
}
|
||||
|
||||
for i, receiver := range receivers {
|
||||
offchainScript, err := bitcointree.ParseVtxoScript(receiver.Descriptor)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
receiverVtxoTaprootKey, _, err := offchainScript.TapTree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
newVtxoScript, err := common.P2TRScript(receiverVtxoTaprootKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Deduct the min relay fee from the very last receiver which is supposed
|
||||
@@ -583,34 +536,27 @@ func (b *txBuilder) BuildAsyncPaymentTransactions(
|
||||
ins, outs, 2, 0, sequences,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
for i := range redeemPtx.Inputs {
|
||||
unconditionnalForfeitPsbt, _ := psbt.NewFromRawBytes(
|
||||
strings.NewReader(unconditionalForfeitTxs[i]), true,
|
||||
)
|
||||
redeemPtx.Inputs[i].WitnessUtxo = unconditionnalForfeitPsbt.Inputs[0].WitnessUtxo
|
||||
redeemPtx.Inputs[i].TaprootInternalKey = unconditionnalForfeitPsbt.Inputs[0].TaprootInternalKey
|
||||
redeemPtx.Inputs[i].TaprootLeafScript = unconditionnalForfeitPsbt.Inputs[0].TaprootLeafScript
|
||||
redeemPtx.Inputs[i].WitnessUtxo = witnessUtxos[i]
|
||||
redeemPtx.Inputs[i].TaprootLeafScript = []*psbt.TaprootTapLeafScript{tapscripts[i]}
|
||||
}
|
||||
|
||||
redeemTx, err := redeemPtx.B64Encode()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
signedRedeemTx, err := b.wallet.SignTransactionTapscript(
|
||||
context.Background(), redeemTx, nil,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
return &domain.AsyncPaymentTxs{
|
||||
RedeemTx: signedRedeemTx,
|
||||
UnconditionalForfeitTxs: unconditionalForfeitTxs,
|
||||
}, nil
|
||||
return signedRedeemTx, nil
|
||||
}
|
||||
|
||||
// TODO use lnd CoinSelect to craft the pool tx
|
||||
|
||||
@@ -362,7 +362,7 @@ func (h *handler) CreatePayment(
|
||||
}
|
||||
}
|
||||
|
||||
redeemTx, unconditionalForfeitTxs, err := h.svc.CreateAsyncPayment(
|
||||
redeemTx, err := h.svc.CreateAsyncPayment(
|
||||
ctx, inputs, receivers,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -370,8 +370,7 @@ func (h *handler) CreatePayment(
|
||||
}
|
||||
|
||||
return &arkv1.CreatePaymentResponse{
|
||||
SignedRedeemTx: redeemTx,
|
||||
UsignedUnconditionalForfeitTxs: unconditionalForfeitTxs,
|
||||
SignedRedeemTx: redeemTx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -382,12 +381,8 @@ func (h *handler) CompletePayment(
|
||||
return nil, status.Error(codes.InvalidArgument, "missing signed redeem tx")
|
||||
}
|
||||
|
||||
if len(req.GetSignedUnconditionalForfeitTxs()) <= 0 {
|
||||
return nil, status.Error(codes.InvalidArgument, "missing signed unconditional forfeit txs")
|
||||
}
|
||||
|
||||
if err := h.svc.CompleteAsyncPayment(
|
||||
ctx, req.GetSignedRedeemTx(), req.GetSignedUnconditionalForfeitTxs(),
|
||||
ctx, req.GetSignedRedeemTx(),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -65,13 +65,6 @@ type vtxoList []domain.Vtxo
|
||||
func (v vtxoList) toProto() []*arkv1.Vtxo {
|
||||
list := make([]*arkv1.Vtxo, 0, len(v))
|
||||
for _, vv := range v {
|
||||
var pendingData *arkv1.PendingPayment
|
||||
if vv.AsyncPayment != nil {
|
||||
pendingData = &arkv1.PendingPayment{
|
||||
RedeemTx: vv.AsyncPayment.RedeemTx,
|
||||
UnconditionalForfeitTxs: vv.AsyncPayment.UnconditionalForfeitTxs,
|
||||
}
|
||||
}
|
||||
list = append(list, &arkv1.Vtxo{
|
||||
Outpoint: &arkv1.Outpoint{
|
||||
Txid: vv.Txid,
|
||||
@@ -84,7 +77,7 @@ func (v vtxoList) toProto() []*arkv1.Vtxo {
|
||||
ExpireAt: vv.ExpireAt,
|
||||
SpentBy: vv.SpentBy,
|
||||
Swept: vv.Swept,
|
||||
PendingData: pendingData,
|
||||
RedeemTx: vv.RedeemTx,
|
||||
Pending: vv.Pending,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user