40 using namespace test::jtx;
43 Account gw{
"gateway"};
44 Account alice{
"alice"};
47 env.fund(XRP(10000), gw, alice, bob);
52 auto jrr = ledgerEntryState(env, gw, alice,
"USD");
53 BEAST_EXPECT(jrr[jss::error] ==
"entryNotFound");
56 env(trust(alice, gw[
"USD"](800)));
58 jrr = ledgerEntryState(env, gw, alice,
"USD");
59 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
60 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"800");
61 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == alice.human());
62 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
63 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"0");
64 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == gw.human());
65 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
68 env(trust(alice, gw[
"USD"](700)));
70 jrr = ledgerEntryState(env, gw, alice,
"USD");
71 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
72 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"700");
73 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == alice.human());
74 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
75 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"0");
76 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == gw.human());
77 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
83 env(trust(alice, gw[
"USD"](0)));
86 jrr = ledgerEntryState(env, gw, alice,
"USD");
87 BEAST_EXPECT(jrr[jss::error] ==
"entryNotFound");
92 env(trust(alice, bob[
"USD"](600)));
95 env(trust(bob, alice[
"USD"](500)));
98 jrr = ledgerEntryState(env, alice, bob,
"USD");
99 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
100 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"500");
101 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == bob.human());
102 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
103 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"600");
104 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == alice.human());
105 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
112 using namespace test::jtx;
114 Env env{*
this, features};
115 Account alice{
"alice"};
118 env.fund(XRP(10000), alice, bob);
121 env(trust(alice, bob[
"USD"](600)));
122 env(trust(bob, alice[
"USD"](700)));
125 env(pay(alice, bob, alice[
"USD"](24)));
126 env.require(balance(bob, alice[
"USD"](24)));
129 env(pay(alice, bob, bob[
"USD"](33)));
130 env.require(balance(bob, alice[
"USD"](57)));
133 env(pay(bob, alice, bob[
"USD"](90)));
134 env.require(balance(bob, alice[
"USD"](-33)));
137 env(pay(alice, bob, bob[
"USD"](733)));
138 env.require(balance(bob, alice[
"USD"](700)));
141 env(pay(bob, alice, bob[
"USD"](1300)));
142 env.require(balance(bob, alice[
"USD"](-600)));
145 env(pay(bob, alice, bob[
"USD"](1)), ter(
tecPATH_DRY));
146 env.require(balance(bob, alice[
"USD"](-600)));
153 std::string(
"Direct Payment: ") + (with_rate ?
"With " :
"Without ") +
" Xfer Fee, " +
154 (subscribe ?
"With " :
"Without ") +
" Subscribe");
155 using namespace test::jtx;
157 Env env{*
this, features};
159 Account gw{
"gateway"};
160 Account alice{
"alice"};
163 env.fund(XRP(10000), gw, alice, bob);
166 env(trust(alice, gw[
"AUD"](100)));
167 env(trust(bob, gw[
"AUD"](100)));
169 env(pay(gw, alice, alice[
"AUD"](1)));
172 env.require(balance(alice, gw[
"AUD"](1)));
175 env(pay(alice, bob, gw[
"AUD"](1)));
178 env.require(balance(alice, gw[
"AUD"](0)));
179 env.require(balance(bob, gw[
"AUD"](1)));
180 env.require(balance(gw, bob[
"AUD"](-1)));
188 env(pay(bob, alice, gw[
"AUD"](0.5)), sendmax(gw[
"AUD"](0.55)));
193 env(pay(bob, alice, gw[
"AUD"](0.5)));
196 env.require(balance(alice, gw[
"AUD"](0.5)));
197 env.require(balance(bob, gw[
"AUD"](with_rate ? 0.45 : 0.5)));
198 env.require(balance(gw, bob[
"AUD"](with_rate ? -0.45 : -0.5)));
204 jvs[jss::accounts].
append(gw.human());
206 jvs[jss::streams].
append(
"transactions");
207 jvs[jss::streams].
append(
"ledger");
208 auto jv = wsc->invoke(
"subscribe", jvs);
209 BEAST_EXPECT(jv[jss::status] ==
"success");
213 using namespace std::chrono_literals;
214 BEAST_EXPECT(wsc->findMsg(5s, [](
auto const& jval) {
215 auto const& t = jval[jss::transaction];
216 return t[jss::TransactionType] == jss::Payment;
218 BEAST_EXPECT(wsc->findMsg(5s, [](
auto const& jval) { return jval[jss::type] ==
"ledgerClosed"; }));
220 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");
227 testcase(
"Payments With Paths and Fees");
228 using namespace test::jtx;
230 Env env{*
this, features};
231 Account gw{
"gateway"};
232 Account alice{
"alice"};
235 env.fund(XRP(10000), gw, alice, bob);
241 env(trust(alice, gw[
"AUD"](100)));
242 env(trust(bob, gw[
"AUD"](100)));
244 env(pay(gw, alice, alice[
"AUD"](4.4)));
245 env.require(balance(alice, gw[
"AUD"](4.4)));
249 env(pay(alice, bob, gw[
"AUD"](1)), sendmax(gw[
"AUD"](1.1)));
250 env.require(balance(alice, gw[
"AUD"](3.3)));
251 env.require(balance(bob, gw[
"AUD"](1)));
254 env(pay(alice, bob, bob[
"AUD"](1)), sendmax(gw[
"AUD"](1.1)));
255 env.require(balance(alice, gw[
"AUD"](2.2)));
256 env.require(balance(bob, gw[
"AUD"](2)));
259 env(pay(alice, bob, gw[
"AUD"](1)), sendmax(alice[
"AUD"](1.1)));
260 env.require(balance(alice, gw[
"AUD"](1.1)));
261 env.require(balance(bob, gw[
"AUD"](3)));
265 env(pay(alice, bob, bob[
"AUD"](1)), sendmax(alice[
"AUD"](1.1)), ter(
tecPATH_DRY));
267 env.require(balance(alice, gw[
"AUD"](1.1)));
268 env.require(balance(bob, gw[
"AUD"](3)));
275 using namespace test::jtx;
277 Env env{*
this, features};
278 Account gw{
"gateway"};
279 Account alice{
"alice"};
282 env.fund(XRP(10000), gw, alice, bob);
285 env(trust(alice, gw[
"USD"](600)));
286 env(trust(bob, gw[
"USD"](700)));
288 env(pay(gw, alice, alice[
"USD"](70)));
289 env(pay(gw, bob, bob[
"USD"](50)));
291 env.require(balance(alice, gw[
"USD"](70)));
292 env.require(balance(bob, gw[
"USD"](50)));
302 env.require(balance(alice, gw[
"USD"](70)));
303 env.require(balance(bob, gw[
"USD"](50)));
308 env.require(balance(alice, gw[
"USD"](65)));
309 env.require(balance(bob, gw[
"USD"](55)));
315 testcase(
std::string(
"Indirect Payment, Multi Path, ") + (with_rate ?
"With " :
"Without ") +
" Xfer Fee, ");
316 using namespace test::jtx;
318 Env env{*
this, features};
319 Account gw{
"gateway"};
320 Account amazon{
"amazon"};
321 Account alice{
"alice"};
323 Account carol{
"carol"};
325 env.fund(XRP(10000), gw, amazon, alice, bob, carol);
328 env(trust(amazon, gw[
"USD"](2000)));
329 env(trust(bob, alice[
"USD"](600)));
330 env(trust(bob, gw[
"USD"](1000)));
331 env(trust(carol, alice[
"USD"](700)));
332 env(trust(carol, gw[
"USD"](1000)));
337 env(pay(gw, bob, bob[
"USD"](100)));
338 env(pay(gw, carol, carol[
"USD"](100)));
343 env(pay(alice, amazon, gw[
"USD"](150)),
344 sendmax(alice[
"USD"](200)),
354 env.require(balance(carol, gw[
"USD"](35)));
358 env.require(balance(alice, carol[
"USD"](-50)));
359 env.require(balance(carol, gw[
"USD"](50)));
361 env.require(balance(alice, bob[
"USD"](-100)));
362 env.require(balance(amazon, gw[
"USD"](150)));
363 env.require(balance(bob, gw[
"USD"](0)));
369 testcase(
"Set Invoice ID on Payment");
370 using namespace test::jtx;
372 Env env{*
this, features};
373 Account alice{
"alice"};
376 env.fund(XRP(10000), alice);
381 jvs[jss::accounts].
append(env.master.human());
383 jvs[jss::streams].
append(
"transactions");
384 BEAST_EXPECT(wsc->invoke(
"subscribe", jvs)[jss::status] ==
"success");
386 char const* invoiceId =
"243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89";
389 auto tx = env.jt(pay(env.master, alice, XRP(10000)), json(sfInvoiceID.fieldName, invoiceId));
390 jv[jss::tx_blob] =
strHex(tx.stx->getSerializer().slice());
391 auto jrr = wsc->invoke(
"submit", jv)[jss::result];
392 BEAST_EXPECT(jrr[jss::status] ==
"success");
393 BEAST_EXPECT(jrr[jss::tx_json][sfInvoiceID.fieldName] == invoiceId);
396 using namespace std::chrono_literals;
397 BEAST_EXPECT(wsc->findMsg(2s, [invoiceId](
auto const& jval) {
398 auto const& t = jval[jss::transaction];
399 return t[jss::TransactionType] == jss::Payment && t[sfInvoiceID.fieldName] == invoiceId;
402 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");