From 27db59c75fb41153407bcab3875b7727da13e309 Mon Sep 17 00:00:00 2001 From: Oliver Eggert Date: Thu, 20 Jun 2024 14:10:21 -0700 Subject: [PATCH] update tutorial to pull from js file --- _code-samples/add-amm-lp/js/add-amm-lp.js | 151 +++++++++++++ _code-samples/add-amm-lp/js/package.json | 6 + .../address_encoding/js/package.json | 2 +- ...-passive-income-as-a-liquidity-provider.md | 200 ++---------------- 4 files changed, 178 insertions(+), 181 deletions(-) create mode 100644 _code-samples/add-amm-lp/js/add-amm-lp.js create mode 100644 _code-samples/add-amm-lp/js/package.json diff --git a/_code-samples/add-amm-lp/js/add-amm-lp.js b/_code-samples/add-amm-lp/js/add-amm-lp.js new file mode 100644 index 0000000000..8732a5ff17 --- /dev/null +++ b/_code-samples/add-amm-lp/js/add-amm-lp.js @@ -0,0 +1,151 @@ +const xrpl = require('xrpl') + +const WS_URL = 'wss://s.altnet.rippletest.net:51233/' +const EXPLORER = 'testnet.xrpl.org' // Optional, for linking + +async function main() { + +// Define the network client +const client = new xrpl.Client(WS_URL) +await client.connect() + +// Get an address funded with XRP from the Faucet +console.log("Requesting address from the faucet...") +const wallet = (await client.fundWallet()).wallet + +// To use an existing account, use code such as the following: +// const wallet = xrpl.Wallet.fromSeed(process.env['USE_SEED']) + +// Acquire TST tokens +console.log("------- Acquire TST tokens ---------") + +const offer = { + "TransactionType": "OfferCreate", + "Account": wallet.address, + "TakerPays": { + currency: "TST", + issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", + value: "5" + }, + // Drops calculation is (amount to buy * price per token * amm trading fees) + "TakerGets": xrpl.xrpToDrops(58) +} + +const prepared_offer = await client.autofill(offer) +console.log("Prepared transaction:", JSON.stringify(prepared_offer, null, 2)) +const signed_offer = wallet.sign(prepared_offer) +console.log("Sending OfferCreate transaction...") +const result_offer = await client.submitAndWait(signed_offer.tx_blob) +console.log(result_offer) +if (result_offer.result.meta.TransactionResult == "tesSUCCESS") { + console.log(`Transaction succeeded: + https://${EXPLORER}/transactions/${signed_offer.hash}`) +} else { + throw `Error sending transaction: ${result_offer}` +} + +// Deposit assets into AMM +console.log("------- Put more assets into the AMM -------") + +const ammdeposit = { + "TransactionType": "AMMDeposit", + "Asset": { + currency: "XRP" + }, + "Asset2": { + currency: "TST", + issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" + }, + "Account": wallet.address, + // Drops calculation is (amount to deposit * price per token) + "Amount": xrpl.xrpToDrops(25), + "Amount2": { + currency: "TST", + issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", + value: "2.5" + }, + "Flags": 0x00100000 +} + +const prepared_deposit = await client.autofill(ammdeposit) +console.log("Prepared transaction:", JSON.stringify(prepared_deposit, null, 2)) +const signed_deposit = wallet.sign(prepared_deposit) +console.log(`Sending AMMDeposit transaction ...`) +const lp_deposit = await client.submitAndWait(signed_deposit.tx_blob) +console.log(lp_deposit) + +if (lp_deposit.result.meta.TransactionResult == "tesSUCCESS") { + console.log(`Transaction succeeded: + https://${EXPLORER}/transactions/${signed_deposit.hash}`) +} else { + throw `Error sending transaction: ${lp_deposit}` +} + +// Vote on fees +console.log("------- Vote for a 0.6% trading fee -------") + +const ammvote = { + "TransactionType": "AMMVote", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "TST", + "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" + }, + "Account": wallet.address, + "TradingFee": 600 +} + +const prepared_vote = await client.autofill(ammvote) +console.log("Prepared transaction:", JSON.stringify(prepared_vote, null, 2)) +const signed_vote = wallet.sign(prepared_vote) +console.log(`Sending AMMVote transaction ...`) +const response_vote = await client.submitAndWait(signed_vote.tx_blob) +if (response_vote.result.meta.TransactionResult == "tesSUCCESS") { + console.log(`Transaction succeeded: + https://${EXPLORER}/transactions/${signed_vote.hash}`) +} else { + console.error("Error sending transaction:", response_vote) +} + +console.log("------- Pull some money out of AMM -------") + +// Withdraw by redeeming LP tokens +const ammwithdraw = { + "TransactionType": "AMMWithdraw", + "Asset": { + "currency": "XRP" + }, + "Asset2": { + "currency": "TST", + "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" + }, + "Account": wallet.address, + "LPTokenIn": { + currency: "039C99CD9AB0B70B32ECDA51EAAE471625608EA2", + issuer: "rhQWjbT5CQJ2fgHKn6FjRrYbGPKmoS3EhD", + value: "2940" + }, + "Flags": 0x00010000 +} + +const prepared_withdraw = await client.autofill(ammwithdraw) +console.log("Prepared transaction:", JSON.stringify(prepared_withdraw, null, 2)) +const signed_withdraw = wallet.sign(prepared_withdraw) +console.log(`Sending AMMWithdraw transaction ...`) +const response_withdraw = await client.submitAndWait(signed_withdraw.tx_blob) + +if (response_withdraw.result.meta.TransactionResult == "tesSUCCESS") { + console.log(`Transaction succeeded: + https://${EXPLORER}/transactions/${signed_withdraw.hash}`) +} else { + console.error("Error sending transaction:", response_withdraw) +} + +// Disconnect when done (If you omit this, Node.js won't end the process) +await client.disconnect() + +} + +main() \ No newline at end of file diff --git a/_code-samples/add-amm-lp/js/package.json b/_code-samples/add-amm-lp/js/package.json new file mode 100644 index 0000000000..5f2ffebf6a --- /dev/null +++ b/_code-samples/add-amm-lp/js/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "xrpl": "^3.0.0" + } +} + \ No newline at end of file diff --git a/_code-samples/address_encoding/js/package.json b/_code-samples/address_encoding/js/package.json index 280649015f..1e47163670 100644 --- a/_code-samples/address_encoding/js/package.json +++ b/_code-samples/address_encoding/js/package.json @@ -4,6 +4,6 @@ "license": "MIT", "//": "Change the license to something appropriate. You may want to use 'UNLICENSED' if you are just starting out.", "dependencies": { - "base-x": "*", + "base-x": "*" } } diff --git a/docs/tutorials/how-tos/use-tokens/earn-passive-income-as-a-liquidity-provider.md b/docs/tutorials/how-tos/use-tokens/earn-passive-income-as-a-liquidity-provider.md index e542a101b2..bea3d0ff96 100644 --- a/docs/tutorials/how-tos/use-tokens/earn-passive-income-as-a-liquidity-provider.md +++ b/docs/tutorials/how-tos/use-tokens/earn-passive-income-as-a-liquidity-provider.md @@ -1,11 +1,8 @@ --- -parent: use-tokens.html +html: earn-passive-income-as-a-liquidity-provider.html seo: description: Provide liquidity for an Automated Market Maker (AMM) and earn income from trading fees. -embed_xrpl_js: true status: not_enabled -filters: - - interactive_steps labels: - Decentralized Exchange - Tokens @@ -21,207 +18,50 @@ Providing liquidity for an [Automated Market Maker (AMM)](../../../concepts/toke ## Prerequisites -- You must have an XRP Ledger address and some XRP. This tutorial will use a funded address generated from the `Testnet` [Faucet](/resources/dev-tools/xrp-faucets). -- You should be familiar with the Getting Started instructions for your preferred client library. This page provides examples for the following: - - **JavaScript** with the [xrpl.js library](https://github.com/XRPLF/xrpl.js/) **version 2.11.0 or later**. See [Get Started Using JavaScript](../../javascript/build-apps/get-started.md) for setup steps. - - You can also read along and use the interactive steps in your browser without any setup. -- You should have a basic understanding of how [tokens](../../../concepts/tokens/index.md) work in the XRP Ledger. -- You may want to read about [Automated Market Makers in the XRP Ledger](../../../concepts/tokens/decentralized-exchange/automated-market-makers.md) first. -- This tutorial uses a pre-existing `XRP/TST` AMM pool on `Testnet`. +- You should be familiar with basic usage of the [xrpl.js client library](https://github.com/XRPLF/xrpl.js/). See [Get Started Using JavaScript](../build-apps/get-started.md) for setup steps. +- The AMM for the asset pair you want to trade must already exist in the ledger. This tutorial uses an AMM on Testnet which has been set up in advance, connecting the following assets: - currency: "TST", - issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", +| Currency Code | Issuer | Notes | +|---|---|---| +| XRP | N/A | Testnet XRP is functionally similar to XRP, but holds no real-world value. You can get it for free from a [faucet](/resources/dev-tools/xrp-faucets). +| TST | `rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd` | A test token pegged to XRP at a rate of approximately 10 XRP per 1 TST. The issuer has existing Offers on the XRP Ledger Testnet to buy and sell these tokens. This token has no [transfer fee](../../../concepts/tokens/transfer-fees.md) or [Tick Size](../../../concepts/tokens/decentralized-exchange/ticksize.md) set. | -Offers for XRP at a rate of 10 XRP ≈ 1 TST (+15% fee each way) +For instructions on creating an AMM for a different currency pair, see [Create an Automated Market Maker](../../how-tos/use-tokens/create-an-automated-market-maker.md). -## Example Code +## Source Code -Complete sample code for all of the steps of these tutorials is available under the [MIT license](https://github.com/XRPLF/xrpl-dev-portal/blob/master/LICENSE). - -- See [Code Samples: Create an AMM](https://github.com/XRPLF/xrpl-dev-portal/tree/master/_code-samples/create-amm/) in the source repository for this website. +See {% repo-link path="_code-samples/add-amm-lp/js/" %}Code Samples: Add AMM LP{% /repo-link %} for the full source code for this tutorial. ## Steps -### 1. Connect to the network +### 1. Connect to the network and generate credentials -```javascript -const xrpl = require('xrpl') - -const WS_URL = 'wss://s.devnet.rippletest.net:51233/' -const EXPLORER = 'devnet.xrpl.org' // Optional, for linking - -async function main() { - // Define the network client - const client = new xrpl.Client(WS_URL) - await client.connect() - - // ... custom code goes here - - // Disconnect when done (If you omit this, Node.js won't end the process) - await client.disconnect() -} - -main() -``` +{% code-snippet file="/_code-samples/add-amm-lp/js/add-amm-lp.js" language="js" from="// Define the network client" before="// Acquire TST tokens" /%} -### 2. Generate credentials +### 2. Acquire TST tokens -```javascript -// Get an address funded with XRP from the Faucet ------------------------------------------- -console.log("Requesting address from the faucet...") -const wallet = (await client.fundWallet()).wallet - -// To use an existing account, use code such as the following: -// const wallet = xrpl.Wallet.fromSeed(process.env['USE_SEED']) -``` +{% code-snippet file="/_code-samples/add-amm-lp/js/add-amm-lp.js" language="js" from="// Acquire TST tokens" before="// Deposit assets into AMM" /%} -### 3. Acquire TST tokens - -```javascript -const offer = { - "TransactionType": "OfferCreate", - "Account": wallet.address, - "TakerPays": { - currency: "TST", - issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", - value: "5" - }, - // Drops calculation is (amount to buy * price per token * amm trading fees) - "TakerGets": xrpl.xrpToDrops(57.5) -} - -const prepared_offer = await client.autofill(offer) -console.log("Prepared transaction:", JSON.stringify(prepared_offer, null, 2)) -const signed_offer = wallet.sign(prepared_offer) -console.log("Sending OfferCreate transaction...") -const result_offer = await client.submitAndWait(signed_offer.tx_blob) -console.log(result_offer) -if (result_offer.result.meta.TransactionResult == "tesSUCCESS") { - console.log(`Transaction succeeded: - https://${EXPLORER}/transactions/${signed_offer.hash}`) -} else { - throw `Error sending transaction: ${result_offer}` -} -``` - - -### 4. Deposit assets to the AMM +### 3. Deposit assets to the AMM You can contribute either one or both assets to an AMM pool. Contributing just one asset can be easier, but incurs a fee that is debited from the LP Tokens paid out. If you contribute both assets in the pool, you aren't charged a fee. -```javascript -console.log("------- Put more assets into the AMM -------") - -const ammdeposit = { - "TransactionType": "AMMDeposit", - "Asset": { - currency: "XRP" - }, - "Asset2": { - currency: "TST", - issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" - }, - "Account": wallet.address, - // Drops calculation is (amount to deposit * price per token) - "Amount": xrpl.xrpToDrops(10), - "Amount2": { - currency: "TST", - issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd", - value: "1" - }, - "Flags": 0x00100000 -} - -const prepared_deposit = await client.autofill(ammdeposit) -console.log("Prepared transaction:", JSON.stringify(prepared_deposit, null, 2)) -const signed_deposit = wallet.sign(prepared_deposit) -console.log(`Sending AMMDeposit transaction ...`) -const lp_deposit = await client.submitAndWait(signed_deposit.tx_blob) -console.log(lp_deposit) - -if (lp_deposit.result.meta.TransactionResult == "tesSUCCESS") { - console.log(`Transaction succeeded: - https://${EXPLORER}/transactions/${signed_deposit.hash}`) -} else { - throw `Error sending transaction: ${lp_deposit}` -} -``` +{% code-snippet file="/_code-samples/add-amm-lp/js/add-amm-lp.js" language="js" from="// Deposit assets into AMM" before="// Vote on fees" /%} -### 5. Vote on trading fees +### 4. Vote on trading fees This step isn't required, but you're encouraged to submit a vote for a fee structure you believe makes sense. -```javascript -console.log("------- Vote for a 0.6% trading fee -------") - -const ammvote = { - "TransactionType": "AMMVote", - "Asset": { - "currency": "XRP" - }, - "Asset2": { - "currency": "TST", - "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" - }, - "Account": wallet.address, - "TradingFee": 600 -} - -const prepared_vote = await client.autofill(ammvote) -console.log("Prepared transaction:", JSON.stringify(prepared_vote, null, 2)) -const signed_vote = wallet.sign(prepared_vote) -console.log(`Sending AMMVote transaction ...`) -const response_vote = await client.submitAndWait(signed_vote.tx_blob) -if (response_vote.result.meta.TransactionResult == "tesSUCCESS") { - console.log(`Transaction succeeded: - https://${EXPLORER}/transactions/${signed_vote.hash}`) -} else { - console.error("Error sending transaction:", response_vote) -} -``` +{% code-snippet file="/_code-samples/add-amm-lp/js/add-amm-lp.js" language="js" from="// Vote on fees" before="// Withdraw by redeeming LP tokens" /%} -### 6. Withdraw assets from the AMM +### 5. Withdraw assets from the AMM Similar to depositing assets, you can withdraw either one or both assets from the AMM pool. Withdrawing a single asset incurs a fee, while withdrawing both does not. When you withdraw by redeeming LP Tokens, you are paid out in both assets. -```javascript -console.log("------- Pull some money out of AMM -------") - -// Withdraw by redeeming LP tokens. -const ammwithdraw = { - "TransactionType": "AMMWithdraw", - "Asset": { - "currency": "XRP" - }, - "Asset2": { - "currency": "TST", - "issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd" - }, - "Account": wallet.address, - "LPTokenIn": { - currency: "039C99CD9AB0B70B32ECDA51EAAE471625608EA2", - issuer: "rhQWjbT5CQJ2fgHKn6FjRrYbGPKmoS3EhD", - value: "2940" - }, - "Flags": 0x00010000 -} - -const prepared_withdraw = await client.autofill(ammwithdraw) -console.log("Prepared transaction:", JSON.stringify(prepared_withdraw, null, 2)) -const signed_withdraw = wallet.sign(prepared_withdraw) -console.log(`Sending AMMWithdraw transaction ...`) -const response_withdraw = await client.submitAndWait(signed_withdraw.tx_blob) - -if (response_withdraw.result.meta.TransactionResult == "tesSUCCESS") { - console.log(`Transaction succeeded: - https://${EXPLORER}/transactions/${signed_withdraw.hash}`) -} else { - console.error("Error sending transaction:", response_withdraw) -} -``` \ No newline at end of file +{% code-snippet file="/_code-samples/add-amm-lp/js/add-amm-lp.js" language="js" from="// Withdraw by redeeming LP tokens" before="// Disconnect when done" /%}