1
+ if ( typeof module !== "undefined" ) {
2
+ // Use var here because const/let are block-scoped to the if statement.
3
+ var xrpl = require ( 'xrpl' )
4
+ }
5
+
6
+ const client = new xrpl . Client ( "wss://s.devnet.rippletest.net:51233" ) ;
7
+ client . connect ( )
8
+
9
+ let aliceWallet = null
10
+ let bobWallet = null
11
+ let issuerWallet = null
12
+
13
+ let aliceWalletBalance = null
14
+ let bobWalletBalance = null
15
+
16
+ // Add an event listener to the startButton
17
+ document . addEventListener ( "DOMContentLoaded" , function ( ) {
18
+ startButton . addEventListener ( "click" , start )
19
+ aCreateOfferButton . addEventListener ( "click" , aliceCreateOffer )
20
+ bCreateOfferButton . addEventListener ( "click" , bobCreateOffer )
21
+ } ) ;
22
+
23
+ // Function to get Alice and Bob balances
24
+
25
+ async function getBalances ( ) {
26
+ aliceWalletBalance = await client . getBalances ( aliceWallet . address )
27
+ bobWalletBalance = await client . getBalances ( bobWallet . address )
28
+
29
+ aliceWalletField . value = `${ aliceWalletBalance [ 0 ] . value } XRP / ${ aliceWalletBalance [ 1 ] . value } USD`
30
+ bobWalletField . value = `${ bobWalletBalance [ 0 ] . value } XRP / ${ bobWalletBalance [ 1 ] . value } USD`
31
+ }
32
+
33
+ // Function to update AMM
34
+
35
+ async function ammInfoUpdate ( ) {
36
+ const ammInfo = await client . request ( {
37
+ "command" : "amm_info" ,
38
+ "asset" : {
39
+ "currency" : "XRP"
40
+ } ,
41
+ "asset2" : {
42
+ "currency" : "USD" ,
43
+ "issuer" : issuerWallet . address
44
+ } ,
45
+ "ledger_index" : "validated"
46
+ } )
47
+
48
+ ammInfoField . value = JSON . stringify ( ammInfo . result . amm , null , 2 )
49
+ }
50
+
51
+ // Function to update Alice and Bobs offers
52
+
53
+ async function updateOffers ( ) {
54
+ const aliceOffers = await client . request ( {
55
+ "command" : "account_offers" ,
56
+ "account" : aliceWallet . address
57
+ } )
58
+
59
+ if ( aliceOffers . result . offers == "" ) {
60
+ aliceOffersField . value = `No offers.`
61
+ } else {
62
+ aliceOffersField . value = `${ JSON . stringify ( aliceOffers . result . offers , null , 2 ) } `
63
+ }
64
+
65
+ const bobOffers = await client . request ( {
66
+ "command" : "account_offers" ,
67
+ "account" : bobWallet . address
68
+ } )
69
+
70
+ if ( bobOffers . result . offers == "" ) {
71
+ bobOffersField . value = `No offers.`
72
+ } else {
73
+ bobOffersField . value = `${ JSON . stringify ( bobOffers . result . offers , null , 2 ) } `
74
+ }
75
+ }
76
+
77
+ // Function to set up test harness
78
+ async function start ( ) {
79
+
80
+ // Fund wallets and wait for each to complete
81
+ startButton . textContent = "Loading wallets..." ;
82
+
83
+ const issuerStart = client . fundWallet ( )
84
+ const ammStart = client . fundWallet ( )
85
+ const aliceStart = client . fundWallet ( )
86
+ const bobStart = client . fundWallet ( )
87
+
88
+ const [ issuerResult , ammResult , aliceResult , bobResult ] = await Promise . all ( [ issuerStart , ammStart , aliceStart , bobStart ] )
89
+
90
+ issuerWallet = issuerResult . wallet
91
+ const ammWallet = ammResult . wallet
92
+ aliceWallet = aliceResult . wallet
93
+ bobWallet = bobResult . wallet
94
+
95
+ // Set up account settings
96
+ startButton . textContent = "Setting up account settings..." ;
97
+
98
+ const issuerSetRipple = client . submitAndWait ( {
99
+ "TransactionType" : "AccountSet" ,
100
+ "Account" : issuerWallet . address ,
101
+ "SetFlag" : xrpl . AccountSetAsfFlags . asfDefaultRipple
102
+ } , { autofill : true , wallet : issuerWallet } )
103
+
104
+ const ammSetTrust = client . submitAndWait ( {
105
+ "TransactionType" : "TrustSet" ,
106
+ "Account" : ammWallet . address ,
107
+ "LimitAmount" : {
108
+ "currency" : "USD" ,
109
+ "issuer" : issuerWallet . address ,
110
+ "value" : "10000"
111
+ }
112
+ } , { autofill : true , wallet : ammWallet } )
113
+
114
+ const aliceSetTrust = client . submitAndWait ( {
115
+ "TransactionType" : "TrustSet" ,
116
+ "Account" : aliceWallet . address ,
117
+ "LimitAmount" : {
118
+ "currency" : "USD" ,
119
+ "issuer" : issuerWallet . address ,
120
+ "value" : "10000"
121
+ }
122
+ } , { autofill : true , wallet : aliceWallet } )
123
+
124
+ const bobSetTrust = client . submitAndWait ( {
125
+ "TransactionType" : "TrustSet" ,
126
+ "Account" : bobWallet . address ,
127
+ "LimitAmount" : {
128
+ "currency" : "USD" ,
129
+ "issuer" : issuerWallet . address ,
130
+ "value" : "10000"
131
+ }
132
+ } , { autofill : true , wallet : bobWallet } )
133
+
134
+ await Promise . all ( [ issuerSetRipple , ammSetTrust , aliceSetTrust , bobSetTrust ] )
135
+
136
+ // Send USD token
137
+ startButton . textContent = "Sending USD..." ;
138
+
139
+ const issuerAccountInfo = await client . request ( {
140
+ "command" : "account_info" ,
141
+ "account" : issuerWallet . address
142
+ } )
143
+
144
+ let sequence = issuerAccountInfo . result . account_data . Sequence
145
+
146
+ const ammUSD = client . submitAndWait ( {
147
+ "TransactionType" : "Payment" ,
148
+ "Account" : issuerWallet . address ,
149
+ "Amount" : {
150
+ "currency" : "USD" ,
151
+ "value" : "1000" ,
152
+ "issuer" : issuerWallet . address
153
+ } ,
154
+ "Destination" : ammWallet . address ,
155
+ "Sequence" : sequence ++
156
+ } , { autofill : true , wallet : issuerWallet } )
157
+
158
+ const aliceUSD = client . submitAndWait ( {
159
+ "TransactionType" : "Payment" ,
160
+ "Account" : issuerWallet . address ,
161
+ "Amount" : {
162
+ "currency" : "USD" ,
163
+ "value" : "1000" ,
164
+ "issuer" : issuerWallet . address
165
+ } ,
166
+ "Destination" : aliceWallet . address ,
167
+ "Sequence" : sequence ++
168
+ } , { autofill : true , wallet : issuerWallet } )
169
+
170
+ const bobUSD = client . submitAndWait ( {
171
+ "TransactionType" : "Payment" ,
172
+ "Account" : issuerWallet . address ,
173
+ "Amount" : {
174
+ "currency" : "USD" ,
175
+ "value" : "1000" ,
176
+ "issuer" : issuerWallet . address
177
+ } ,
178
+ "Destination" : bobWallet . address ,
179
+ "Sequence" : sequence ++
180
+ } , { autofill : true , wallet : issuerWallet } )
181
+
182
+ await Promise . all ( [ ammUSD , aliceUSD , bobUSD ] )
183
+
184
+ // Update Alice and Bob's XRP and USD balances
185
+
186
+ getBalances ( )
187
+
188
+ // Set up AMM
189
+ startButton . textContent = "Creating AMM..." ;
190
+
191
+ await client . submitAndWait ( {
192
+ "TransactionType" : "AMMCreate" ,
193
+ "Account" : ammWallet . address ,
194
+ "Amount" : "50000000" , // XRP as drops
195
+ "Amount2" : {
196
+ "currency" : "USD" ,
197
+ "issuer" : issuerWallet . address ,
198
+ "value" : "500"
199
+ } ,
200
+ "TradingFee" : 500 // 0.5%
201
+ } , { autofill : true , wallet : ammWallet } )
202
+
203
+ // Update AMM
204
+ ammInfoUpdate ( )
205
+
206
+ startButton . textContent = "Ready (Click to Restart)" ;
207
+
208
+ }
209
+
210
+
211
+ // Submit Alice Offers
212
+ async function aliceCreateOffer ( ) {
213
+
214
+ aCreateOfferButton . textContent = "Creating Offer..."
215
+
216
+ try {
217
+ let aliceTakerGets = null
218
+ let aliceTakerPays = null
219
+
220
+ if ( aliceTakerGetsCurrency . value == 'XRP' ) {
221
+ aliceTakerGets = xrpl . xrpToDrops ( aliceTakerGetsAmount . value )
222
+ } else {
223
+ aliceTakerGets = {
224
+ "currency" : "USD" ,
225
+ "issuer" : issuerWallet . address ,
226
+ "value" : aliceTakerGetsAmount . value
227
+ }
228
+ }
229
+
230
+ if ( aliceTakerPaysCurrency . value == 'XRP' ) {
231
+ aliceTakerPays = xrpl . xrpToDrops ( aliceTakerPaysAmount . value )
232
+ } else {
233
+ aliceTakerPays = {
234
+ "currency" : "USD" ,
235
+ "issuer" : issuerWallet . address ,
236
+ "value" : aliceTakerPaysAmount . value
237
+ }
238
+ }
239
+
240
+ await client . submitAndWait ( {
241
+ "TransactionType" : "OfferCreate" ,
242
+ "Account" : aliceWallet . address ,
243
+ "TakerGets" : aliceTakerGets ,
244
+ "TakerPays" : aliceTakerPays
245
+ } , { autofill : true , wallet : aliceWallet } )
246
+
247
+ updateOffers ( )
248
+ getBalances ( )
249
+ ammInfoUpdate ( )
250
+
251
+ } catch ( error ) {
252
+ aliceOffersField . value = `${ error . message } `
253
+ }
254
+
255
+ aCreateOfferButton . textContent = "Create Another Offer"
256
+ }
257
+
258
+ // Submit Bob Offers
259
+ async function bobCreateOffer ( ) {
260
+
261
+ bCreateOfferButton . textContent = "Creating Offer..."
262
+
263
+ try {
264
+ let bobTakerGets = null
265
+ let bobTakerPays = null
266
+
267
+ if ( bobTakerGetsCurrency . value == 'XRP' ) {
268
+ bobTakerGets = xrpl . xrpToDrops ( bobTakerGetsAmount . value )
269
+ } else {
270
+ bobTakerGets = {
271
+ "currency" : "USD" ,
272
+ "issuer" : issuerWallet . address ,
273
+ "value" : bobTakerGetsAmount . value
274
+ }
275
+ }
276
+
277
+ if ( bobTakerPaysCurrency . value == 'XRP' ) {
278
+ bobTakerPays = xrpl . xrpToDrops ( bobTakerPaysAmount . value )
279
+ } else {
280
+ bobTakerPays = {
281
+ "currency" : "USD" ,
282
+ "issuer" : issuerWallet . address ,
283
+ "value" : bobTakerPaysAmount . value
284
+ }
285
+ }
286
+
287
+ await client . submitAndWait ( {
288
+ "TransactionType" : "OfferCreate" ,
289
+ "Account" : bobWallet . address ,
290
+ "TakerGets" : bobTakerGets ,
291
+ "TakerPays" : bobTakerPays
292
+ } , { autofill : true , wallet : bobWallet } )
293
+
294
+ updateOffers ( )
295
+ getBalances ( )
296
+ ammInfoUpdate ( )
297
+
298
+ } catch ( error ) {
299
+ bobOffersField . value = `${ error . message } `
300
+ }
301
+
302
+ bCreateOfferButton . textContent = "Create Another Offer"
303
+ }
0 commit comments