import * as React from 'react'; import { useThemeHooks } from '@redocly/theme/core/hooks'; import { clsx } from 'clsx' import { Client, type Wallet, type TxResponse, dropsToXrp } from 'xrpl' import { errorNotif, TESTNET_URL } from '../utils' export interface InitializationProps { existingClient: Client | undefined, alert, // From useAlert() setClient: React.Dispatch>, setBalance: React.Dispatch>, setSendingWallet: React.Dispatch>, setIsInitEnabled: React.Dispatch>, setConnectionReady: React.Dispatch>, partialPaymentParams: { setPpIssuerWallet: React.Dispatch>, setPpWidthPercent: React.Dispatch>, ppCurrencyCode: string } } async function setUpForPartialPayments ( client: Client, sendingWallet: Wallet, setPpIssuerWallet: React.Dispatch>, setPpWidthPercent: React.Dispatch>, ppCurrencyCode: string, ) { console.debug("Starting partial payment setup...") // Causing loader to appear because no longer 0% setPpWidthPercent(1) let ppIssuerWallet; // 1. Get a funded address to use as issuer try { ppIssuerWallet = (await client.fundWallet()).wallet setPpIssuerWallet(ppIssuerWallet) } catch(error) { console.log("Error getting issuer address for partial payments:", error) return } setPpWidthPercent(20) // 2. Set Default Ripple on issuer let resp: TxResponse = await client.submitAndWait({ TransactionType: "AccountSet", Account: ppIssuerWallet.address, SetFlag: 8 // asfDefaultRipple }, { wallet: ppIssuerWallet }) if (resp === undefined) { console.log("Couldn't set Default Ripple for partial payment issuer") return } setPpWidthPercent(40) // 3. Make a trust line from sending address to issuer resp = await client.submitAndWait({ TransactionType: "TrustSet", Account: sendingWallet.address, LimitAmount: { currency: ppCurrencyCode, value: "1000000000", // arbitrarily, 1 billion fake currency issuer: ppIssuerWallet.address } }, { wallet: sendingWallet }) if (resp === undefined) { console.log("Error making trust line to partial payment issuer") return } setPpWidthPercent(60) // 4. Issue fake currency to main sending address resp = await client.submitAndWait({ TransactionType: "Payment", Account: ppIssuerWallet.address, Destination: sendingWallet.address, Amount: { currency: ppCurrencyCode, value: "1000000000", issuer: ppIssuerWallet.address } }, { wallet: ppIssuerWallet }) if (resp === undefined) { console.log("Error sending fake currency from partial payment issuer") return } setPpWidthPercent(80) // 5. Place offer to buy issued currency for XRP // When sending the partial payment, the sender consumes their own offer (!) // so they end up paying themselves issued currency then delivering XRP. resp = await client.submitAndWait({ TransactionType: "OfferCreate", Account: sendingWallet.address, TakerGets: "1000000000000000", // 1 billion XRP TakerPays: { currency: ppCurrencyCode, value: "1000000000", issuer: ppIssuerWallet.address } }, { wallet: sendingWallet }) if (resp === undefined) { console.log("Error placing order to enable partial payments") return } setPpWidthPercent(100) // Done. Enable "Send Partial Payment" button console.log("Done getting ready to send partial payments.") } async function onInitClick( props: InitializationProps ): Promise { const { existingClient, alert, // From useAlert() setClient, setBalance, setSendingWallet, setIsInitEnabled, setConnectionReady, partialPaymentParams } = {...props} if(existingClient) { console.log("Already initializing!") return } console.log("Connecting to Testnet WebSocket...") const client = new Client(TESTNET_URL) client.on('connected', () => { setConnectionReady(true) }) client.on('disconnected', (code) => { setConnectionReady(false) }) setClient(client) await client.connect() console.debug("Getting a sending address from the faucet...") try { const fundResponse = await client.fundWallet() const sendingWallet = fundResponse.wallet setSendingWallet(sendingWallet) // Using Number(...) can result in loss of precision since Number is smaller than the precision of XRP, // but this shouldn't affect the learning tool as that much XRP is not given to any test account. setBalance(Number(dropsToXrp(fundResponse.balance))) setIsInitEnabled(false) await setUpForPartialPayments( client, sendingWallet, partialPaymentParams.setPpIssuerWallet, partialPaymentParams.setPpWidthPercent, partialPaymentParams.ppCurrencyCode, ) } catch(error) { console.error(error) errorNotif(alert, "There was an error with the XRP Ledger Testnet Faucet. Reload this page to try again.") return } } export function InitButton({ isInitEnabled, toInit }: { isInitEnabled: boolean, toInit: InitializationProps }): React.JSX.Element { const { useTranslate } = useThemeHooks(); const { translate } = useTranslate() return (
{!isInitEnabled && (
 
)} {translate("Set up the necessary Testnet XRP addresses to send test payments.")}
) }