// 1. Generate // 2. Connect // The code for these steps is handled by interactive-tutorial.js onCurrentRouteLoaded(() => { const EXPLORER = $("#connect-button").data("explorer") $("#get-foo").click( async (event) => { const block = $(event.target).closest(".interactive-block") const wallet = get_wallet(event) if (!wallet) {return} const currency_code = "FOO" const issue_quantity = "1000" block.find(".loader").show() show_log(block, "

Funding an issuer address with the faucet...

") const issuer = (await api.fundWallet()).wallet show_log(block, `

Got issuer ${issuer.address}.

`) $(".foo-issuer").text(issuer.address) // Update display in the "Create AMM" step // Enable issuer DefaultRipple ---------------------------------------------- const issuer_setup_tx = { "TransactionType": "AccountSet", "Account": issuer.address, "SetFlag": xrpl.AccountSetAsfFlags.asfDefaultRipple } add_memo(event, issuer_setup_tx) const issuer_setup_result = await api.submitAndWait(issuer_setup_tx, {autofill: true, wallet: issuer} ) if (issuer_setup_result.result.meta.TransactionResult == "tesSUCCESS") { show_log(block, `

✅ Issuer DefaultRipple enabled

`) } else { show_error(block, `Error sending transaction:
${pretty_print(issuer_setup_result)}
`) } // Create trust line to issuer ---------------------------------------------- const trust_tx = { "TransactionType": "TrustSet", "Account": wallet.address, "LimitAmount": { "currency": currency_code, "issuer": issuer.address, "value": "10000000000" // Large limit, arbitrarily chosen } } add_memo(event, trust_tx) const trust_result = await api.submitAndWait(trust_tx, {autofill: true, wallet: wallet}) if (trust_result.result.meta.TransactionResult == "tesSUCCESS") { show_log(block, `

✅ Trust line created

`) } else { show_error(block, `Error sending transaction:
${pretty_print(trust_result)}
`) } // Issue tokens ------------------------------------------------------------- const issue_tx = { "TransactionType": "Payment", "Account": issuer.address, "Amount": { "currency": currency_code, "value": issue_quantity, "issuer": issuer.address }, "Destination": wallet.address } add_memo(event, issue_tx) const issue_result = await api.submitAndWait(issue_tx, {autofill: true, wallet: issuer}) if (issue_result.result.meta.TransactionResult == "tesSUCCESS") { show_log(block, `

✅ Tokens issued

`) $("#get-foo").data("foo-acquired", true).prop("disabled", true).addClass("disabled").addClass("done") } else { show_error(block, `Error sending transaction:
${pretty_print(issue_result)}
`) } block.find(".loader").hide() if ($("#get-foo").data("foo-acquired") && $("#buy-tst").data("tst-acquired")) { complete_step("Acquire tokens") } }) $("#buy-tst").click( async (event) => { const block = $(event.target).closest(".interactive-block") const wallet = get_wallet(event) if (!wallet) {return} block.find(".loader").show() const tx_json = { "TransactionType": "OfferCreate", "Account": wallet.address, "TakerPays": { currency: "TST", issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", value: "25" }, "TakerGets": xrpl.xrpToDrops(25*10*1.16) } add_memo(event, tx_json) const offer_result = await api.submitAndWait(tx_json, {autofill: true, wallet: wallet}) if (offer_result.result.meta.TransactionResult == "tesSUCCESS") { show_log(block, `

✅ TST offer placed

`) const balance_changes = xrpl.getBalanceChanges(offer_result.result.meta) for (const bc of balance_changes) { if (bc.account != wallet.address) {continue} for (const bal of bc.balances) { if (bal.currency == "TST") { show_log(block, `

Got ${bal.value} ${bal.currency}.${bal.issuer}.

`) break } } break } $("#buy-tst").data("tst-acquired", true).prop("disabled", true).addClass("disabled").addClass("done") } else { show_error(block, `

Transaction failed:

${pretty_print(offer_result)}
`) } block.find(".loader").hide() if ($("#get-foo").data("foo-acquired") && $("#buy-tst").data("tst-acquired")) { complete_step("Acquire tokens") } }) $("#check-for-amm").click( async (event) => { const block = $(event.target).closest(".interactive-block") const foo_issuer_address = $("#issuer-address").text() block.find(".output-area").html("") block.find(".loader").show() try { const amm_info = await api.request({ "command": "amm_info", "asset": { "currency": "TST", "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" }, "asset2": { "currency": "FOO", "issuer": foo_issuer_address }, "ledger_index": "validated" }) show_log(block, `
${pretty_print}amm_info
`) } catch(err) { if (err.data.error === 'actNotFound') { show_log(block, `

✅ No AMM exists yet for the pair FOO.${foo_issuer_address} / TST.rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd.`) complete_step("Check for AMM") } else { show_error(block, err) } } block.find(".loader").hide() }) $("#look-up-ammcreate-cost").click( async (event) => { const block = $(event.target).closest(".interactive-block") block.find(".loader").show() let amm_fee_drops = "5000000" try { const ss = await api.request({"command": "server_state"}) amm_fee_drops = ss.result.state.validated_ledger.reserve_inc.toString() show_log(block, `

Current AMMCreate transaction cost: ${xrpl.dropsToXrp(amm_fee_drops)} XRP (${amm_fee_drops} drops)

`) complete_step("Look up AMMCreate cost") } catch(err) { show_error(block, `Error looking up AMMCreate tx cost: ${err}`) } block.find(".loader").hide() }) $("#create-amm").click( async (event) => { const block = $(event.target).closest(".interactive-block") const wallet = get_wallet(event) if (!wallet) {return} amm_fee_drops = $("#ammcreate-cost-drops").text() if (!amm_fee_drops) {return} block.find(".output-area").html("") block.find(".loader").show() const asset_amount = $("#asset-amount").val() const asset2_amount = $("#asset2-amount").val() const asset2_issuer_address = $("#issuer-address").text() const trading_fee = Math.floor($("#trading-fee").val()*1000) // Convert from % const ammcreate_tx = { "TransactionType": "AMMCreate", "Account": wallet.address, "Amount": { currency: "TST", issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", value: asset_amount }, "Amount2": { "currency": "FOO", "issuer": asset2_issuer_address, "value": asset2_amount }, "TradingFee": 500, // 0.5% "Fee": amm_fee_drops } add_memo(event, ammcreate_tx) const ammcreate_result = await api.submitAndWait(ammcreate_tx, {autofill: true, wallet: wallet, fail_hard: true}) if (ammcreate_result.result.meta.TransactionResult == "tesSUCCESS") { show_log(block, `

AMM created:

${pretty_print(ammcreate_result)}
`) complete_step("Create AMM") } else { console.error(ammcreate_result) show_error(block, `Error sending transaction: ${ammcreate_result.result.meta.TransactionResult}`) } block.find(".loader").hide() }) $("#check-amm-info").click( async (event) => { const block = $(event.target).closest(".interactive-block") const foo_issuer_address = $("#issuer-address").text() block.find(".output-area").html("") block.find(".loader").show() try { const amm_info = await api.request({ "command": "amm_info", "asset": { "currency": "TST", "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" }, "asset2": { "currency": "FOO", "issuer": foo_issuer_address }, "ledger_index": "validated" }) show_log(block, `

AMM Info:

${pretty_print(amm_info)}
`) const lp_token = amm_info.result.amm.lp_token show_log(block, `

The AMM account ${lp_token.issuer} has ${lp_token.value} total LP tokens outstanding, and uses the currency code ${lp_token.currency}.

`) const amount = amm_info.result.amm.amount const amount2 = amm_info.result.amm.amount2 show_log(block, `

In its pool, the AMM holds ${amount.value} ${amount.currency}.${amount.issuer} and ${amount2.value} ${amount2.currency}.${amount2.issuer}

`) complete_step("Check AMM info") } catch(err) { show_error(block, err) } block.find(".loader").hide() }) $("#check-trust-lines").click( async (event) => { const block = $(event.target).closest(".interactive-block") const address = get_address() if (!address) {return} block.find(".output-area").html("") block.find(".loader").show() try { const account_lines = await api.request({ "command": "account_lines", "account": address, "ledger_index": "validated" }) show_log(block, `

Trust lines:

${pretty_print(account_lines)}
`) complete_step("Check trust lines") } catch(err) { show_error(block, err) } block.find(".loader").hide() }) })