40 using namespace test::jtx;
43 Account
const gw{
"gateway"};
44 Account
const alice{
"alice"};
45 Account
const bob{
"bob"};
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
const alice{
"alice"};
116 Account
const bob{
"bob"};
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
const gw{
"gateway"};
160 Account
const alice{
"alice"};
161 Account
const bob{
"bob"};
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(
219 5s, [](
auto const& jval) { return jval[jss::type] ==
"ledgerClosed"; }));
221 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");
228 testcase(
"Payments With Paths and Fees");
229 using namespace test::jtx;
231 Env env{*
this, features};
232 Account
const gw{
"gateway"};
233 Account
const alice{
"alice"};
234 Account
const bob{
"bob"};
236 env.fund(XRP(10000), gw, alice, bob);
242 env(trust(alice, gw[
"AUD"](100)));
243 env(trust(bob, gw[
"AUD"](100)));
245 env(pay(gw, alice, alice[
"AUD"](4.4)));
246 env.require(balance(alice, gw[
"AUD"](4.4)));
250 env(pay(alice, bob, gw[
"AUD"](1)), sendmax(gw[
"AUD"](1.1)));
251 env.require(balance(alice, gw[
"AUD"](3.3)));
252 env.require(balance(bob, gw[
"AUD"](1)));
255 env(pay(alice, bob, bob[
"AUD"](1)), sendmax(gw[
"AUD"](1.1)));
256 env.require(balance(alice, gw[
"AUD"](2.2)));
257 env.require(balance(bob, gw[
"AUD"](2)));
260 env(pay(alice, bob, gw[
"AUD"](1)), sendmax(alice[
"AUD"](1.1)));
261 env.require(balance(alice, gw[
"AUD"](1.1)));
262 env.require(balance(bob, gw[
"AUD"](3)));
266 env(pay(alice, bob, bob[
"AUD"](1)), sendmax(alice[
"AUD"](1.1)), ter(
tecPATH_DRY));
268 env.require(balance(alice, gw[
"AUD"](1.1)));
269 env.require(balance(bob, gw[
"AUD"](3)));
276 using namespace test::jtx;
278 Env env{*
this, features};
279 Account
const gw{
"gateway"};
280 Account
const alice{
"alice"};
281 Account
const bob{
"bob"};
283 env.fund(XRP(10000), gw, alice, bob);
286 env(trust(alice, gw[
"USD"](600)));
287 env(trust(bob, gw[
"USD"](700)));
289 env(pay(gw, alice, alice[
"USD"](70)));
290 env(pay(gw, bob, bob[
"USD"](50)));
292 env.require(balance(alice, gw[
"USD"](70)));
293 env.require(balance(bob, gw[
"USD"](50)));
303 env.require(balance(alice, gw[
"USD"](70)));
304 env.require(balance(bob, gw[
"USD"](50)));
309 env.require(balance(alice, gw[
"USD"](65)));
310 env.require(balance(bob, gw[
"USD"](55)));
317 std::string(
"Indirect Payment, Multi Path, ") + (with_rate ?
"With " :
"Without ") +
319 using namespace test::jtx;
321 Env env{*
this, features};
322 Account
const gw{
"gateway"};
323 Account
const amazon{
"amazon"};
324 Account
const alice{
"alice"};
325 Account
const bob{
"bob"};
326 Account
const carol{
"carol"};
328 env.fund(XRP(10000), gw, amazon, alice, bob, carol);
331 env(trust(amazon, gw[
"USD"](2000)));
332 env(trust(bob, alice[
"USD"](600)));
333 env(trust(bob, gw[
"USD"](1000)));
334 env(trust(carol, alice[
"USD"](700)));
335 env(trust(carol, gw[
"USD"](1000)));
340 env(pay(gw, bob, bob[
"USD"](100)));
341 env(pay(gw, carol, carol[
"USD"](100)));
347 env(pay(alice, amazon, gw[
"USD"](150)),
348 sendmax(alice[
"USD"](200)),
363 env.require(balance(carol, gw[
"USD"](35)));
367 env.require(balance(alice, carol[
"USD"](-50)));
368 env.require(balance(carol, gw[
"USD"](50)));
370 env.require(balance(alice, bob[
"USD"](-100)));
371 env.require(balance(amazon, gw[
"USD"](150)));
372 env.require(balance(bob, gw[
"USD"](0)));
378 testcase(
"Set Invoice ID on Payment");
379 using namespace test::jtx;
381 Env env{*
this, features};
382 Account
const alice{
"alice"};
385 env.fund(XRP(10000), alice);
390 jvs[jss::accounts].
append(env.master.human());
392 jvs[jss::streams].
append(
"transactions");
393 BEAST_EXPECT(wsc->invoke(
"subscribe", jvs)[jss::status] ==
"success");
395 char const* invoiceId =
"243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89";
399 env.jt(pay(env.master, alice, XRP(10000)), json(sfInvoiceID.fieldName, invoiceId));
400 jv[jss::tx_blob] =
strHex(tx.stx->getSerializer().slice());
401 auto jrr = wsc->invoke(
"submit", jv)[jss::result];
402 BEAST_EXPECT(jrr[jss::status] ==
"success");
403 BEAST_EXPECT(jrr[jss::tx_json][sfInvoiceID.fieldName] == invoiceId);
406 using namespace std::chrono_literals;
407 BEAST_EXPECT(wsc->findMsg(2s, [invoiceId](
auto const& jval) {
408 auto const& t = jval[jss::transaction];
409 return t[jss::TransactionType] == jss::Payment && t[sfInvoiceID.fieldName] == invoiceId;
412 BEAST_EXPECT(wsc->invoke(
"unsubscribe", jv)[jss::status] ==
"success");