// 1. Generate // 2. Connect // The code for these steps is handled by interactive-tutorial.js window.onRouteChange(() => { 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, ``)
} 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, ``)
$("#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, ``)
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, `${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}.
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()
})
})