62 env.fund(XRP(10000), gw, alice, bob);
67 auto jrr = ledgerEntryState(env, gw, alice,
"USD");
68 BEAST_EXPECT(jrr[jss::error] ==
"entryNotFound");
71 env(trust(alice, gw[
"USD"](800)));
73 jrr = ledgerEntryState(env, gw, alice,
"USD");
74 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
75 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"800");
76 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == alice.human());
77 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
78 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"0");
79 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == gw.human());
80 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
83 env(trust(alice, gw[
"USD"](700)));
85 jrr = ledgerEntryState(env, gw, alice,
"USD");
86 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
87 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"700");
88 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == alice.human());
89 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
90 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"0");
91 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == gw.human());
92 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
98 env(trust(alice, gw[
"USD"](0)));
101 jrr = ledgerEntryState(env, gw, alice,
"USD");
102 BEAST_EXPECT(jrr[jss::error] ==
"entryNotFound");
107 env(trust(alice, bob[
"USD"](600)));
110 env(trust(bob, alice[
"USD"](500)));
113 jrr = ledgerEntryState(env, alice, bob,
"USD");
114 BEAST_EXPECT(jrr[jss::node][sfBalance.fieldName][jss::value] ==
"0");
115 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::value] ==
"500");
116 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::issuer] == bob.human());
117 BEAST_EXPECT(jrr[jss::node][sfHighLimit.fieldName][jss::currency] ==
"USD");
118 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::value] ==
"600");
119 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::issuer] == alice.human());
120 BEAST_EXPECT(jrr[jss::node][sfLowLimit.fieldName][jss::currency] ==
"USD");
129 Env env{*
this, features};
133 env.fund(XRP(10000), alice, bob);
136 env(trust(alice, bob[
"USD"](600)));
137 env(trust(bob, alice[
"USD"](700)));
140 env(pay(alice, bob, alice[
"USD"](24)));
141 env.require(Balance(bob, alice[
"USD"](24)));
144 env(pay(alice, bob, bob[
"USD"](33)));
145 env.require(Balance(bob, alice[
"USD"](57)));
148 env(pay(bob, alice, bob[
"USD"](90)));
149 env.require(Balance(bob, alice[
"USD"](-33)));
152 env(pay(alice, bob, bob[
"USD"](733)));
153 env.require(Balance(bob, alice[
"USD"](700)));
156 env(pay(bob, alice, bob[
"USD"](1300)));
157 env.require(Balance(bob, alice[
"USD"](-600)));
160 env(pay(bob, alice, bob[
"USD"](1)), Ter(
tecPATH_DRY));
161 env.require(Balance(bob, alice[
"USD"](-600)));
168 std::string(
"Direct Payment: ") + (withRate ?
"With " :
"Without ") +
" Xfer Fee, " +
169 (subscribe ?
"With " :
"Without ") +
" Subscribe");
172 Env env{*
this, features};
178 env.fund(XRP(10000), gw, alice, bob);
181 env(trust(alice, gw[
"AUD"](100)));
182 env(trust(bob, gw[
"AUD"](100)));
184 env(pay(gw, alice, alice[
"AUD"](1)));
187 env.require(Balance(alice, gw[
"AUD"](1)));
190 env(pay(alice, bob, gw[
"AUD"](1)));
193 env.require(Balance(alice, gw[
"AUD"](0)));
194 env.require(Balance(bob, gw[
"AUD"](1)));
195 env.require(Balance(gw, bob[
"AUD"](-1)));
203 env(pay(bob, alice, gw[
"AUD"](0.5)), Sendmax(gw[
"AUD"](0.55)));
208 env(pay(bob, alice, gw[
"AUD"](0.5)));
211 env.require(Balance(alice, gw[
"AUD"](0.5)));
212 env.require(Balance(bob, gw[
"AUD"](withRate ? 0.45 : 0.5)));
213 env.require(Balance(gw, bob[
"AUD"](withRate ? -0.45 : -0.5)));
219 jvs[jss::accounts].
append(gw.human());
221 jvs[jss::streams].
append(
"transactions");
222 jvs[jss::streams].
append(
"ledger");
223 auto jv = wsc->invoke(
"subscribe", jvs);
224 BEAST_EXPECT(jv[jss::status] ==
"success");
228 using namespace std::chrono_literals;
229 BEAST_EXPECT(wsc->findMsg(5s, [](
auto const& jval) {
230 auto const& t = jval[jss::transaction];
231 return t[jss::TransactionType] == jss::Payment;
233 BEAST_EXPECT(wsc->findMsg(
234 5s, [](
auto const& jval) { return jval[jss::type] ==
"ledgerClosed"; }));
236 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");
243 testcase(
"Payments With Paths and Fees");
246 Env env{*
this, features};
251 env.fund(XRP(10000), gw, alice, bob);
257 env(trust(alice, gw[
"AUD"](100)));
258 env(trust(bob, gw[
"AUD"](100)));
260 env(pay(gw, alice, alice[
"AUD"](4.4)));
261 env.require(Balance(alice, gw[
"AUD"](4.4)));
265 env(pay(alice, bob, gw[
"AUD"](1)), Sendmax(gw[
"AUD"](1.1)));
266 env.require(Balance(alice, gw[
"AUD"](3.3)));
267 env.require(Balance(bob, gw[
"AUD"](1)));
270 env(pay(alice, bob, bob[
"AUD"](1)), Sendmax(gw[
"AUD"](1.1)));
271 env.require(Balance(alice, gw[
"AUD"](2.2)));
272 env.require(Balance(bob, gw[
"AUD"](2)));
275 env(pay(alice, bob, gw[
"AUD"](1)), Sendmax(alice[
"AUD"](1.1)));
276 env.require(Balance(alice, gw[
"AUD"](1.1)));
277 env.require(Balance(bob, gw[
"AUD"](3)));
281 env(pay(alice, bob, bob[
"AUD"](1)), Sendmax(alice[
"AUD"](1.1)), Ter(
tecPATH_DRY));
283 env.require(Balance(alice, gw[
"AUD"](1.1)));
284 env.require(Balance(bob, gw[
"AUD"](3)));
293 Env env{*
this, features};
298 env.fund(XRP(10000), gw, alice, bob);
301 env(trust(alice, gw[
"USD"](600)));
302 env(trust(bob, gw[
"USD"](700)));
304 env(pay(gw, alice, alice[
"USD"](70)));
305 env(pay(gw, bob, bob[
"USD"](50)));
307 env.require(Balance(alice, gw[
"USD"](70)));
308 env.require(Balance(bob, gw[
"USD"](50)));
318 env.require(Balance(alice, gw[
"USD"](70)));
319 env.require(Balance(bob, gw[
"USD"](50)));
324 env.require(Balance(alice, gw[
"USD"](65)));
325 env.require(Balance(bob, gw[
"USD"](55)));
332 std::string(
"Indirect Payment, Multi Path, ") + (withRate ?
"With " :
"Without ") +
336 Env env{*
this, features};
338 Account const amazon{
"amazon"};
343 env.fund(XRP(10000), gw, amazon, alice, bob, carol);
346 env(trust(amazon, gw[
"USD"](2000)));
347 env(trust(bob, alice[
"USD"](600)));
348 env(trust(bob, gw[
"USD"](1000)));
349 env(trust(carol, alice[
"USD"](700)));
350 env(trust(carol, gw[
"USD"](1000)));
355 env(pay(gw, bob, bob[
"USD"](100)));
356 env(pay(gw, carol, carol[
"USD"](100)));
362 env(pay(alice, amazon, gw[
"USD"](150)),
363 Sendmax(alice[
"USD"](200)),
377 env.require(Balance(carol, gw[
"USD"](35)));
381 env.require(Balance(alice, carol[
"USD"](-50)));
382 env.require(Balance(carol, gw[
"USD"](50)));
384 env.require(Balance(alice, bob[
"USD"](-100)));
385 env.require(Balance(amazon, gw[
"USD"](150)));
386 env.require(Balance(bob, gw[
"USD"](0)));
392 testcase(
"Set Invoice ID on Payment");
395 Env env{*
this, features};
399 env.fund(XRP(10000), alice);
404 jvs[jss::accounts].
append(env.master.human());
406 jvs[jss::streams].
append(
"transactions");
407 BEAST_EXPECT(wsc->invoke(
"subscribe", jvs)[jss::status] ==
"success");
409 char const* invoiceId =
"243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89";
413 env.jt(pay(env.master, alice, XRP(10000)), Json(sfInvoiceID.fieldName, invoiceId));
414 jv[jss::tx_blob] =
strHex(tx.stx->getSerializer().slice());
415 auto jrr = wsc->invoke(
"submit", jv)[jss::result];
416 BEAST_EXPECT(jrr[jss::status] ==
"success");
417 BEAST_EXPECT(jrr[jss::tx_json][sfInvoiceID.fieldName] == invoiceId);
420 using namespace std::chrono_literals;
421 BEAST_EXPECT(wsc->findMsg(2s, [invoiceId](
auto const& jval) {
422 auto const& t = jval[jss::transaction];
423 return t[jss::TransactionType] == jss::Payment && t[sfInvoiceID.fieldName] == invoiceId;
426 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");