mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2025-11-05 04:15:50 +00:00
DEX trade tutorial: more progress (incomplete)
There's still a bug that causes the code's predictions to be wrong.
This commit is contained in:
@@ -15,17 +15,113 @@ async function main() {
|
|||||||
await client.connect()
|
await client.connect()
|
||||||
|
|
||||||
// Get credentials from the Testnet Faucet -----------------------------------
|
// Get credentials from the Testnet Faucet -----------------------------------
|
||||||
console.log("Requesting address from the Testnet faucet...")
|
// console.log("Requesting address from the Testnet faucet...")
|
||||||
const wallet = (await client.fundWallet()).wallet
|
// const wallet = (await client.fundWallet()).wallet
|
||||||
console.log(`Got address ${wallet.address}.`)
|
// console.log(`Got address ${wallet.address}.`)
|
||||||
|
const wallet = xrpl.Wallet.fromSeed("SEED VALUE HERE") // temp for testing: don't fund every time
|
||||||
|
|
||||||
|
// Define the proposed trade.
|
||||||
|
const we_want = {
|
||||||
|
currency: "TST",
|
||||||
|
issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd",
|
||||||
|
value: "25"}
|
||||||
|
|
||||||
|
// 250 TST * 10 XRP per TST * 1.15 fx cost
|
||||||
|
const we_spend = {currency: "XRP", value: xrpl.xrpToDrops(25*10*1.15)}
|
||||||
|
// "Quality" is defined as TakerPays ÷ TakerGets. The lower the "quality"
|
||||||
|
// number, the better the proposed exchange rate is for the taker.
|
||||||
|
const proposed_quality = Number(we_spend.value / we_want.value)
|
||||||
|
|
||||||
|
// Look up Offers. -----------------------------------------------------------
|
||||||
|
// To buy TST, look up Offers where "TakerGets" is TST:
|
||||||
|
const orderbook_resp = await client.request({
|
||||||
|
"command": "book_offers",
|
||||||
|
"taker": wallet.address,
|
||||||
|
"ledger_index": "current",
|
||||||
|
"taker_gets": we_want,
|
||||||
|
"taker_pays": we_spend
|
||||||
|
})
|
||||||
|
console.log(JSON.stringify(orderbook_resp.result, null, 2))
|
||||||
|
|
||||||
|
// Estimate whether a proposed Offer would execute immediately, and...
|
||||||
|
// If so, how much of it? (Partial execution is possible)
|
||||||
|
// If not, how much liquidity is above it? (How deep in the order book would
|
||||||
|
// other Offers have to go before ours would get taken?)
|
||||||
|
|
||||||
|
const offers = orderbook_resp.result.offers
|
||||||
|
const want_amt = Number(we_want.value)
|
||||||
|
let running_total = 0
|
||||||
|
if (!offers) {
|
||||||
|
console.log(`No Offers in the matching book.
|
||||||
|
Offer probably won't execute immediately.`)
|
||||||
|
} else {
|
||||||
|
for (o of offers) {
|
||||||
|
if (o.quality <= proposed_quality) {
|
||||||
|
console.log(`Matching Offer found, funded with ${o.owner_funds}`)
|
||||||
|
running_total += Number(o.owner_funds)
|
||||||
|
if (running_total >= want_amt) {
|
||||||
|
console.log("Full Offer will probably fill")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Offers are in ascending quality order, so no others after this
|
||||||
|
// will match, either
|
||||||
|
console.log(`Remaining orders too expensive.`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Total matched: ${Math.min(running_total, want_amt)}`)
|
||||||
|
if (running_total > 0 && running_total < want_amt) {
|
||||||
|
console.log(`Remaining ${want_amt - running_total} would probably be
|
||||||
|
placed on top of the order book.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (running_total = 0) {
|
||||||
|
// If part of the Offer was expected to cross, then the rest would be placed
|
||||||
|
// at the top of the order book. If none did, then there might be other
|
||||||
|
// Offers going the same direction as ours already on the books with an
|
||||||
|
// equal or better rate. This code counts how much liquidity is likely to be
|
||||||
|
// above ours.
|
||||||
|
|
||||||
|
// Unlike above, this time we check for Offers going the same direction as
|
||||||
|
// ours, so TakerGets and TakerPays are reversed from the previous
|
||||||
|
// book_offers request.
|
||||||
|
const orderbook2_resp = await client.request({
|
||||||
|
"command": "book_offers",
|
||||||
|
"taker": wallet.address,
|
||||||
|
"ledger_index": "current",
|
||||||
|
"taker_gets": we_spend,
|
||||||
|
"taker_pays": we_want
|
||||||
|
})
|
||||||
|
console.log(JSON.stringify(orderbook2_resp.result, null, 2))
|
||||||
|
|
||||||
|
// Since TakerGets/TakerPays are reversed, the quality is the inverse.
|
||||||
|
// You could also calculate this as 1/proposed_quality.
|
||||||
|
const offered_quality = Number(we_want.value / we_spend.value)
|
||||||
|
|
||||||
|
const offers2 = orderbook2_resp.result.offers
|
||||||
|
let running_total2 = 0
|
||||||
|
if (!offers2) {
|
||||||
|
console.log(`No similar Offers in the book. Ours would be the first.`)
|
||||||
|
} else {
|
||||||
|
for (o of offers2) {
|
||||||
|
if (o.quality <= offered_quality) {
|
||||||
|
console.log(`Existing offer found, funded with ${o.owner_funds}`)
|
||||||
|
running_total2 += Number(o.owner_funds)
|
||||||
|
} else {
|
||||||
|
console.log(`Remaining orders are below where ours would be placed.`)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Our Offer would be placed below at least ${running_total2} ${we_spend.currency}`)
|
||||||
|
if (running_total > 0 && running_total < want_amt) {
|
||||||
|
console.log(`Remaining ${want_amt - running_total} will probably be
|
||||||
|
placed on top of the order book.`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Look up Offers
|
|
||||||
const orderbook = await client.getOrderbook(
|
|
||||||
{currency: "TST", issuer: "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd"}, // TakerPays
|
|
||||||
{currency: "XRP"}, // TakerGets
|
|
||||||
{ledger_index: "current", taker: wallet.address} // options
|
|
||||||
)
|
|
||||||
console.log(JSON.stringify(orderbook, null, 2))
|
|
||||||
|
|
||||||
// Depending on your use case, you may want to present options to the user
|
// Depending on your use case, you may want to present options to the user
|
||||||
// here with estimates of the cost to buy (or proceeds from selling) the
|
// here with estimates of the cost to buy (or proceeds from selling) the
|
||||||
@@ -37,12 +133,8 @@ async function main() {
|
|||||||
const offer_1 = {
|
const offer_1 = {
|
||||||
"TransactionType": "OfferCreate",
|
"TransactionType": "OfferCreate",
|
||||||
"Account": wallet.address,
|
"Account": wallet.address,
|
||||||
"TakerPays": {
|
"TakerPays": we_want,
|
||||||
"currency": "TST",
|
"TakerGets": we_spend.value // since it's XRP
|
||||||
"issuer": "rP9jPyP5kyvFRb6ZiRghAGw5u8SGAmU4bd",
|
|
||||||
"value": "25"
|
|
||||||
},
|
|
||||||
"TakerGets": xrpl.xrpToDrops(300)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const prepared = await client.autofill(offer_1)
|
const prepared = await client.autofill(offer_1)
|
||||||
|
|||||||
Reference in New Issue
Block a user