forked from stellar/go
-
Notifications
You must be signed in to change notification settings - Fork 1
/
builder.go
158 lines (140 loc) · 5.48 KB
/
builder.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package bridge
import (
"encoding/json"
"strconv"
b "github.com/stellar/go/build"
shared "github.com/stellar/go/services/internal/bridge-compliance-shared"
"github.com/stellar/go/services/internal/bridge-compliance-shared/http/helpers"
)
// OperationType is the type of operation
type OperationType string
const (
// OperationTypeCreateAccount represents create_account operation
OperationTypeCreateAccount OperationType = "create_account"
// OperationTypePayment represents payment operation
OperationTypePayment OperationType = "payment"
// OperationTypePathPayment represents path_payment operation
OperationTypePathPayment OperationType = "path_payment"
// OperationTypeManageOffer represents manage_offer operation
OperationTypeManageOffer OperationType = "manage_offer"
// OperationTypeCreatePassiveOffer represents create_passive_offer operation
OperationTypeCreatePassiveOffer OperationType = "create_passive_offer"
// OperationTypeSetOptions represents set_options operation
OperationTypeSetOptions OperationType = "set_options"
// OperationTypeChangeTrust represents change_trust operation
OperationTypeChangeTrust OperationType = "change_trust"
// OperationTypeAllowTrust represents allow_trust operation
OperationTypeAllowTrust OperationType = "allow_trust"
// OperationTypeAccountMerge represents account_merge operation
OperationTypeAccountMerge OperationType = "account_merge"
// OperationTypeInflation represents inflation operation
OperationTypeInflation OperationType = "inflation"
// OperationTypeManageData represents manage_data operation
OperationTypeManageData OperationType = "manage_data"
)
// BuilderRequest represents request made to /builder endpoint of bridge server
type BuilderRequest struct {
Source string
SequenceNumber string `json:"sequence_number"`
Operations []Operation
Signers []string
}
// Process parses operations and creates OperationBody object for each operation
func (r BuilderRequest) Process() error {
var err error
for i, operation := range r.Operations {
var operationBody OperationBody
switch operation.Type {
case OperationTypeCreateAccount:
var createAccount CreateAccountOperationBody
err = json.Unmarshal(operation.RawBody, &createAccount)
operationBody = createAccount
case OperationTypePayment:
var payment PaymentOperationBody
err = json.Unmarshal(operation.RawBody, &payment)
operationBody = payment
case OperationTypePathPayment:
var pathPayment PathPaymentOperationBody
err = json.Unmarshal(operation.RawBody, &pathPayment)
operationBody = pathPayment
case OperationTypeManageOffer:
var manageOffer ManageOfferOperationBody
err = json.Unmarshal(operation.RawBody, &manageOffer)
operationBody = manageOffer
case OperationTypeCreatePassiveOffer:
var manageOffer ManageOfferOperationBody
err = json.Unmarshal(operation.RawBody, &manageOffer)
manageOffer.PassiveOffer = true
operationBody = manageOffer
case OperationTypeSetOptions:
var setOptions SetOptionsOperationBody
err = json.Unmarshal(operation.RawBody, &setOptions)
operationBody = setOptions
case OperationTypeChangeTrust:
var changeTrust ChangeTrustOperationBody
err = json.Unmarshal(operation.RawBody, &changeTrust)
operationBody = changeTrust
case OperationTypeAllowTrust:
var allowTrust AllowTrustOperationBody
err = json.Unmarshal(operation.RawBody, &allowTrust)
operationBody = allowTrust
case OperationTypeAccountMerge:
var accountMerge AccountMergeOperationBody
err = json.Unmarshal(operation.RawBody, &accountMerge)
operationBody = accountMerge
case OperationTypeInflation:
var inflation InflationOperationBody
err = json.Unmarshal(operation.RawBody, &inflation)
operationBody = inflation
case OperationTypeManageData:
var manageData ManageDataOperationBody
err = json.Unmarshal(operation.RawBody, &manageData)
operationBody = manageData
default:
return helpers.NewInvalidParameterError("operations["+strconv.Itoa(i)+"][type]", "Invalid operation type.")
}
if err != nil {
return helpers.NewInvalidParameterError("operations["+strconv.Itoa(i)+"][body]", "Operation is invalid: "+err.Error())
}
r.Operations[i].Body = operationBody
}
return nil
}
// Validate validates if the request is correct.
func (r BuilderRequest) Validate() error {
if !shared.IsValidAccountID(r.Source) {
return helpers.NewInvalidParameterError("source", "Source parameter must start with `G`.")
}
for i, signer := range r.Signers {
if !shared.IsValidSecret(signer) {
return helpers.NewInvalidParameterError("signers["+strconv.Itoa(i)+"]", "Signer must start with `S`.")
}
}
for _, operation := range r.Operations {
err := operation.Body.Validate()
if err != nil {
return err
}
}
return nil
}
// Operation struct contains operation type and body
type Operation struct {
Type OperationType
RawBody json.RawMessage `json:"body"` // Delay parsing until we know operation type
Body OperationBody `json:"-"` // Created during processing stage
}
// OperationBody interface is a common interface for builder operations
type OperationBody interface {
ToTransactionMutator() b.TransactionMutator
Validate() error
}
// BuilderResponse represents response returned by /builder endpoint of bridge server
type BuilderResponse struct {
helpers.SuccessResponse
TransactionEnvelope string `json:"transaction_envelope"`
}
// Marshal marshals BuilderResponse
func (response *BuilderResponse) Marshal() ([]byte, error) {
return json.MarshalIndent(response, "", " ")
}