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
|
package xmrpayclnt_test
import (
"bytes"
"encoding/json"
"fmt"
"log"
"net/http"
"net/http/httptest"
"net/url"
"time"
"gitlab.com/moneropay/moneropay/v2/pkg/model"
xmrpay "git.samanthony.xyz/xmrpayclnt"
)
func ExampleCallbackHandler() {
// Mock the MoneroPay server's POST /receive endpoint for the
// sake of the example
xmrPaySrv := httptest.NewServer(mockReceivePostHandler{})
xmrPaySrvUrl, err := url.Parse(xmrPaySrv.URL)
if err != nil {
log.Fatal(err)
}
// Create a callback handler that will listen on
// http://localhost:57904/moneropay?abcxyz... for callbacks from
// the MoneroPay server
cbUrl, err := url.Parse("http://localhost:57904/moneropay")
if err != nil {
log.Fatal(err)
}
cbSrv := http.NewServeMux()
cbHlr := xmrpay.NewCallbackHandler(cbUrl)
cbSrv.Handle("POST "+cbUrl.Path, cbHlr)
go func() {
if err := http.ListenAndServe(cbUrl.Host, cbSrv); err != nil {
log.Fatal(err)
}
}()
// Request a transfer and register a callback for it
clnt := xmrpay.New(xmrPaySrvUrl)
resp, cb, err := clnt.NewTxWithCallback(123, "lorem ipsum", cbHlr)
if err != nil {
log.Fatal(err)
}
defer cb.Close()
fmt.Printf("POST /receive response: %s %d %q\n", resp.Address, resp.Amount, resp.Description)
// Wait for the transaction to finish
<-cb.Complete
fmt.Println("funds have been received")
// Output:
// POST /receive response: abcxyz 123 "lorem ipsum"
// funds have been received
}
type mockReceivePostHandler struct{}
func (mockReceivePostHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost || r.URL.Path != "/receive" {
panic(fmt.Sprintf("bad request: %s %s", r.Method, r.URL))
}
var req model.ReceivePostRequest
dec := json.NewDecoder(r.Body)
if err := dec.Decode(&req); err != nil {
panic(err)
}
// Send callbacks
go func() {
var cb model.CallbackResponse
cb.Amount.Expected = req.Amount
cb.Description = req.Description
cbData, err := json.Marshal(cb)
if err != nil {
panic(err)
}
period := time.Second
timer := time.NewTimer(period)
for i := 0; i < 3; i++ {
<-timer.C
timer.Reset(period)
_, err := http.Post(req.CallbackUrl, "application/json", bytes.NewBuffer(cbData))
if err != nil {
panic(err)
}
}
// Transaction is finally complete
cb.Complete = true
cbData, err = json.Marshal(cb)
if err != nil {
panic(err)
}
_, err = http.Post(req.CallbackUrl, "application/json", bytes.NewBuffer(cbData))
if err != nil {
panic(err)
}
}()
resp := model.ReceivePostResponse{
Address: "abcxyz",
Amount: req.Amount,
Description: req.Description,
}
enc := json.NewEncoder(w)
if err := enc.Encode(resp); err != nil {
panic(err)
}
}
|