All pages
Powered by GitBook
1 of 4

Loading...

Loading...

Loading...

Loading...

Creating Accounts

Before we get into the heart of the matter, lets setup a few wallets.

Creating wallets

Let's add some wallet creation logic. We might as well create two wallets for some fun.

  console.log('lets fund 2 accounts...')
  const { wallet: wallet1, balance: balance1 } = await client.fundWallet()
  const { wallet: wallet2, balance: balance2 } = await client.fundWallet()
  
  console.log('wallet1', wallet1)
  console.log('wallet2', wallet2)
  
  console.log({ 
      balance1, 
      address1: wallet1.address, //wallet1.seed
      balance2, 
      address2: wallet2.address 
  })

At this point, we should have two wallets with balances of 100 XRP.

We will save these in a more convenient way to reuse them as we progress through this tutorial.

Collect the seed values from the logs for both accounts, and let's create wallets from those seeds from now on. We'll need an issuer and a receiver so here we go:

First, we set the seed in the code

const issuerSeed = "s...";
const receiverSeed = "s...";

Then we create issuer and receiver wallets from the seeds in the main function as follows:

  const issuer = Wallet.fromSeed(issuerSeed);
  const receiver = Wallet.fromSeed(receiverSeed);

Issuing Tokens

In this section we will create fungible tokens or IOUs and transfert them between accounts.

Creating tokens

Dealing with token codes

Token codes can be three letters or a padded hex string. Here is a convenience function to enable codes longer than three letters. This needs to be done to work with our training app, so you will want to include this in your code. This could easily be done via an import for instance, or placed in the index.ts file directly.

Here is the function code:

Enable rippling

For AMMs and the whole process to work, we need to enable rippling from the issuer account. To enable rippling we use the AccountSet transaction with the appropriate flag. Here is the function.

And in the main function of index.ts we can now add, to trigger this

Creating our issued token

To create an issued token, the receiver first needs to add a trust line to the issuer. It's straightforward, we create a TrustSet transaction and sign it with the receiver account.

Once the trustline is set, we send an amount from the issuer to the receiver that is less than the trust line maximum (500M tokens in this case).

Here is the whole file for createToken.ts

We can now call this function from the main function insideindex.ts, remembering to wrap our token currency code with the convertStringToHexPadded function.

We can check in the explorer that the issuer and receiver have balances in the new token at this point.

Token Issuance and Liquidity

This session will cover token issuance and providing liquidity for your tokens using the automatic market maker built in to the XRPL

index.ts
// enable ripling
  await enableRippling({ wallet: issuer, client });
function convertStringToHexPadded(str: string): string {
  // Convert string to hexadecimal
  let hex: string = "";
  for (let i = 0; i < str.length; i++) {
    const hexChar: string = str.charCodeAt(i).toString(16);
    hex += hexChar;
  }

  // Pad with zeros to ensure it's 40 characters long
  const paddedHex: string = hex.padEnd(40, "0");
  return paddedHex.toUpperCase(); // Typically, hex is handled in uppercase
}
async function enableRippling({ wallet, client }: any) {
  const accountSet: AccountSet = {
    TransactionType: "AccountSet",
    Account: wallet.address,
    SetFlag: AccountSetAsfFlags.asfDefaultRipple,
  };

  const prepared = await client.autofill(accountSet);
  const signed = wallet.sign(prepared);
  const result = await client.submitAndWait(signed.tx_blob);

  console.log(result);
  console.log("Enable rippling tx: ", result.result.hash);

  return;
}
createToken.ts
import { TrustSet, convertStringToHex, TrustSetFlags } from "xrpl";
import { Payment } from "xrpl/src/models";

async function createToken({ issuer, receiver, client, tokenCode }: any) {
  // Create the trust line to send the token
  const trustSet: TrustSet = {
    TransactionType: "TrustSet",
    Account: receiver.address,
    LimitAmount: {
      currency: tokenCode,
      issuer: issuer.address,
      value: "500000000", // 500M tokens
    },
    Flags: TrustSetFlags.tfClearNoRipple,
  };
  console.log(trustSet);

  // Receiver opening trust lines
  const preparedTrust = await client.autofill(trustSet);
  const signedTrust = receiver.sign(preparedTrust);
  const resultTrust = await client.submitAndWait(signedTrust.tx_blob);

  console.log(resultTrust);
  console.log("Trust line issuance tx result: ", resultTrust.result.hash);

  // Send the token to the receiver
  const sendPayment: Payment = {
    TransactionType: "Payment",
    Account: issuer.address,
    Destination: receiver.address,
    Amount: {
      currency: tokenCode,
      issuer: issuer.address,
      value: "200000000", // 200M tokens
    },
  };
  console.log(sendPayment);

  const preparedPayment = await client.autofill(sendPayment);
  const signedPayment = issuer.sign(preparedPayment);
  const resultPayment = await client.submitAndWait(signedPayment.tx_blob);

  console.log(resultPayment);
  console.log("Transfer issuance tx result: ", resultPayment.result.hash);


  return;
}

export default createToken;
index.ts
// ... previous code
// create Token
  await createToken({
    issuer,
    receiver,
    client,
    tokenCode: convertStringToHexPadded("LUC"),
  });

Creating an AMM Pool

Now we will create an AMM Pool to provide some liquidity for our new token.

Create an AMM Pool

Now that the receiver has tokens, we can use the receiver's account to create an AMM. Note that this is the usual architecture where the issuer account solely issues the token, and other proprietary accounts hold the token and can create liquidity.

For this example, we will use pools that have XRP as one side.

Here is the createAMM.ts file:

The final main function index.ts should now look like this:

Don't forget to import enableRippling, createToken, createAMM and convertStringToHexPadded if needed.

You can now go to the training website at (password is training-april-2024) and interact with other pools.

You will need to set up Xaman with the receiver account you created above. You can use the family seed import route. If you are new to Xaman don't forget to enable developer mode in the advanced settings and then switch to testnet from the home page of the Xaman app.

Interact with your pool (swap)

Using the training app, connect and add your public address to the list. When you click "view tokens" next to an address you can see that account's available tokens.

You can create Trustlines for tokens you have not interacted with yet. You can swap XRP for other tokens where you have trustlines using the pool view's swap feature.

You may need to mint more XRP for your receiver account. That's where the print money function might come in handy.

Extra credits

Become a liquidity provider for other pools

ou can become a Liquidity Provider for other pools by using the AMMDeposit function: ()

Withdraw from pools

You can also withdraw from pools using your LP tokens by utilizing the AMMWithdraw transaction. ()

createAMM.ts
import { AMMCreate, AMMDeposit, AMMDepositFlags } from "xrpl";
import { OfferCreate, OfferCreateFlags } from "xrpl";

async function createAMM({ issuer, receiver, client, tokenCode }: any) {
  console.log("create AMM", { issuer, receiver, tokenCode });
  let createAmm: AMMCreate = {
    TransactionType: "AMMCreate",
    Account: receiver.address,
    TradingFee: 600,
    Amount: {
      currency: tokenCode,
      issuer: issuer.classicAddress,
      value: "2000000", // 2M tokens
    },
    Amount2: "50000000", // 50 XRP in drops
  };
  console.log(createAmm);

  const prepared = await client.autofill(createAmm);
  const signed = receiver.sign(prepared);
  const result = await client.submitAndWait(signed.tx_blob);

  console.log(result);
  console.log("Create amm tx: ", result.result.hash);

  return;
}

export default createAMM;
https://trainings.xrpl.at/
https://xrpl.org/docs/references/protocol/transactions/types/ammdeposit/
https://xrpl.org/docs/references/protocol/transactions/types/ammwithdraw/
index.ts
const main = async () => {
  console.log("lets get started...");
  await client.connect();

  // retrieve wallets
  const issuer = Wallet.fromSeed(issuerSeed);
  const receiver = Wallet.fromSeed(receiverSeed);

  // enable ripling
  await enableRippling({ wallet: issuer, client });

  // create Token
  await createToken({
    issuer,
    receiver,
    client,
    tokenCode: convertStringToHexPadded("LUC"),
  });

  // create AMM
  await createAMM({
    issuer,
    receiver,
    client,
    tokenCode: convertStringToHexPadded("LUC"),
  });

  await client.disconnect();

  console.log("all done!");
};