Skip to content
This repository was archived by the owner on Sep 12, 2019. It is now read-only.

Commit a6b8b4c

Browse files
committed
Path payments
1 parent e285946 commit a6b8b4c

File tree

9 files changed

+314
-305
lines changed

9 files changed

+314
-305
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ name | | description
8282
--- | --- | ---
8383
`source` | optional | Secret seed of transaction source account. If ommitted it will use the `base_seed` specified in the config file.
8484
`destination` | required | Account ID or Stellar address (ex. `bob*stellar.org`) of payment destination account
85-
`amount` | required | Amount to send
85+
`amount` | required | Amount that destination will receive
8686
`memo_type` | optional | Memo type, one of: `id`, `text`, `hash`, `extra`
87-
`memo` | optional | Memo value, when `memo_type` is `extra` you can include any info here and it will be included in the pre-image of the transaction's memo hash. See the [Stellar Memo Convention](). `id` it must be uint64, when `hash` it must be 32 bytes hex value.
88-
`asset_code` | optional | Asset code (XLM when empty)
89-
`asset_issuer` | optional | Account ID of asset issuer (XLM when empty)
87+
`memo` | optional | Memo value, when `memo_type` is `extra` you can include any info here and it will be included in the pre-image of the transaction's memo hash. See the [Stellar Memo Convention](https://github.com/stellar/stellar-protocol/issues/28). `id` it must be uint64, when `hash` it must be 32 bytes hex value.
88+
`asset_code` | optional | Asset code (XLM when empty) destination will receive
89+
`asset_issuer` | optional | Account ID of asset issuer (XLM when empty) destination will receive
9090
`send_max` | optional | [path_payment] Maximum amount of send_asset to send
9191
`send_asset_code` | optional | [path_payment] Sending asset code (XLM when empty)
9292
`send_asset_issuer` | optional | [path_payment] Account ID of sending asset issuer (XLM when empty)
@@ -118,7 +118,7 @@ http://localhost:8001/payment
118118
Can be used to authorize other accounts to hold your assets.
119119
It will build and submits a transaction with a [`allow_trust`](https://www.stellar.org/developers/learn/concepts/list-of-operations.html#allow-trust) operation.
120120
The source of this transaction will be the account specified by `accounts.authorizing_seed` config parameter.
121-
You should make sure that this account is a low weight signer on the issuing account. See [Multi-sig]() for more information.
121+
You should make sure that this account is a low weight signer on the issuing account. See [Multi-sig](https://www.stellar.org/developers/learn/concepts/multi-sig.html) for more information.
122122

123123
#### Request Parameters
124124

src/github.com/stellar/gateway/bridge/app.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"flag"
66
"fmt"
77
log "github.com/Sirupsen/logrus"
8+
"net/http"
89
"os"
910
"time"
1011

@@ -137,16 +138,23 @@ func NewApp(config config.Config, migrateFlag bool) (app *App, err error) {
137138

138139
err = g.Provide(
139140
&inject.Object{Value: &requestHandler},
141+
&inject.Object{Value: &config},
140142
&inject.Object{Value: &stellartoml.Resolver{}},
141143
&inject.Object{Value: &federation.Resolver{}},
142144
&inject.Object{Value: &h},
145+
&inject.Object{Value: &ts},
143146
&inject.Object{Value: &paymentListener},
147+
&inject.Object{Value: &http.Client{}},
144148
)
145149

146150
if err != nil {
147151
log.Fatal("Injector: ", err)
148152
}
149153

154+
if err := g.Populate(); err != nil {
155+
log.Fatal("Injector: ", err)
156+
}
157+
150158
app = &App{
151159
config: config,
152160
requestHandler: requestHandler,

src/github.com/stellar/gateway/bridge/handlers/main.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import (
88

99
"github.com/stellar/gateway/bridge/config"
1010
"github.com/stellar/gateway/horizon"
11+
"github.com/stellar/gateway/net"
1112
"github.com/stellar/gateway/protocols/federation"
1213
"github.com/stellar/gateway/protocols/stellartoml"
1314
"github.com/stellar/gateway/submitter"
1415
)
1516

1617
type RequestHandler struct {
1718
Config *config.Config `inject:""`
19+
Client net.HttpClientInterface `inject:""`
1820
Horizon horizon.HorizonInterface `inject:""`
1921
StellarTomlResolver stellartoml.ResolverInterface `inject:""`
2022
FederationResolver federation.ResolverInterface `inject:""`

src/github.com/stellar/gateway/bridge/handlers/request_handler_payment.go

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package handlers
33
import (
44
"encoding/hex"
55
"encoding/json"
6+
"fmt"
67
log "github.com/Sirupsen/logrus"
78
"io/ioutil"
89
"net/http"
@@ -34,6 +35,9 @@ func (rh *RequestHandler) Payment(w http.ResponseWriter, r *http.Request) {
3435
assetIssuer := r.PostFormValue("asset_issuer")
3536
memoType := r.PostFormValue("memo_type")
3637
memo := r.PostFormValue("memo")
38+
sendMax := r.PostFormValue("send_max")
39+
sendAssetCode := r.PostFormValue("send_asset_code")
40+
sendAssetIssuer := r.PostFormValue("send_asset_issuer")
3741
extraMemo := r.PostFormValue("extra_memo")
3842

3943
if extraMemo != "" && rh.Config.Compliance != nil {
@@ -48,7 +52,7 @@ func (rh *RequestHandler) Payment(w http.ResponseWriter, r *http.Request) {
4852
ExtraMemo: extraMemo,
4953
}
5054

51-
resp, err := http.PostForm(
55+
resp, err := rh.Client.PostForm(
5256
*rh.Config.Compliance+"/send",
5357
request.ToValues(),
5458
)
@@ -115,6 +119,45 @@ func (rh *RequestHandler) Payment(w http.ResponseWriter, r *http.Request) {
115119
return
116120
}
117121

122+
var payWithMutator *b.PayWithPath
123+
124+
if sendMax != "" {
125+
// Path payment
126+
var sendAsset b.Asset
127+
if sendAssetCode != "" && sendAssetIssuer != "" {
128+
sendAsset = b.CreditAsset(sendAssetCode, sendAssetIssuer)
129+
} else if sendAssetCode == "" && sendAssetIssuer == "" {
130+
sendAsset = b.NativeAsset()
131+
} else {
132+
log.Print("Missing send asset param.")
133+
server.Write(w, h.NewErrorResponse(h.PaymentMissingParamAsset))
134+
return
135+
}
136+
137+
payWith := b.PayWith(sendAsset, sendMax)
138+
139+
for i := 0; ; i++ {
140+
codeFieldName := fmt.Sprintf("path[%d][asset_code]", i)
141+
issuerFieldName := fmt.Sprintf("path[%d][asset_issuer]", i)
142+
143+
// If the element does not exist in PostForm break the loop
144+
if _, exists := r.PostForm[codeFieldName]; !exists {
145+
break
146+
}
147+
148+
code := r.PostFormValue(codeFieldName)
149+
issuer := r.PostFormValue(issuerFieldName)
150+
151+
if code == "" && issuer == "" {
152+
payWith = payWith.Through(b.NativeAsset())
153+
} else {
154+
payWith = payWith.Through(b.CreditAsset(code, issuer))
155+
}
156+
}
157+
158+
payWithMutator = &payWith
159+
}
160+
118161
var operationBuilder interface{}
119162

120163
if assetCode != "" && assetIssuer != "" {
@@ -125,16 +168,26 @@ func (rh *RequestHandler) Payment(w http.ResponseWriter, r *http.Request) {
125168
return
126169
}
127170

128-
operationBuilder = b.Payment(
171+
mutators := []interface{}{
129172
b.Destination{destinationObject.AccountId},
130173
b.CreditAmount{assetCode, issuerKeypair.Address(), amount},
131-
)
174+
}
175+
176+
if payWithMutator != nil {
177+
mutators = append(mutators, *payWithMutator)
178+
}
179+
180+
operationBuilder = b.Payment(mutators...)
132181
} else if assetCode == "" && assetIssuer == "" {
133182
mutators := []interface{}{
134183
b.Destination{destinationObject.AccountId},
135184
b.NativeAmount{amount},
136185
}
137186

187+
if payWithMutator != nil {
188+
mutators = append(mutators, *payWithMutator)
189+
}
190+
138191
// Check if destination account exist
139192
_, err = rh.Horizon.LoadAccount(destinationObject.AccountId)
140193
if err != nil {

0 commit comments

Comments
 (0)