💡

XRPL開発(xrpl.js)でよく使用する処理を汎用的なメソッドとして定義する

2024/05/22に公開

この記事ではXRPL開発で、よく使用する処理を汎用的なメソッドとして定義することについて紹介します。

最近色々と実装して見る中で、実際のXRPL開発では、トランザクションの送信などを汎用的な処理にしないとプロダクションレベルに仕上げるのは難しそうだな、と感じたので、作ってみた汎用的なメソッドの一部をご紹介できればなと思い、執筆しました。

また個人的には、utilsディレクトリに格納することが多いです。

1. trustSet.jsの作成

トラストラインを設定する汎用的なメソッドを定義します。

// utils/trustSet.js

// トラストラインを設定する関数
export async function setTrustLine(client, wallet, currency, issuer, limit) {
  try {
    const trustSet = {
      TransactionType: 'TrustSet',
      Account: wallet.classicAddress,
      LimitAmount: {
        currency: currency,
        issuer: issuer,
        value: limit,
      },
    };
    const response = await client.submitAndWait(trustSet, { wallet });
    return response;
  } catch (error) {
    console.error(`Error setting trust line: ${error}`);
    throw error;
  }
}

使用方法

import { Client, Wallet } from 'xrpl';
import { setTrustLine } from './utils/trustSet.js';

...

// クライアントとウォレットの初期化
const client = new Client('wss://s.altnet.rippletest.net:51233');
await client.connect();

const wallet = Wallet.fromSeed('s████████████████████████████');

const currency = 'USD';
const issuer = 'r████████████████████████████';
const limit = '1000';

// トラストラインの設定
await setTrustLine(client, wallet, currency, issuer, limit);

client.disconnect();

2. offerCreate.jsの作成

offerCreateトランザクションを送信する汎用的なメソッドを定義します。

// utils/offerCreate.js

// オファーを作成する関数
export async function createOffer(client, wallet, takerGets, takerPays) {
  try {
    const offerCreate = {
      TransactionType: 'OfferCreate',
      Account: wallet.classicAddress,
      TakerGets: takerGets,
      TakerPays: takerPays,
    };
    const response = await client.submitAndWait(offerCreate, { wallet });
    console.log(`Offer created for ${wallet.classicAddress}:`, response);
    return response;
  } catch (error) {
    console.error(
      `Error creating offer for ${wallet.classicAddress}: ${error}`
    );
    throw error;
  }
}

使用方法

import { Client, Wallet } from 'xrpl';
import { createOffer } from './utils/offerCreate.js';

...

// クライアントとウォレットの初期化
const client = new Client('wss://s.altnet.rippletest.net:51233');
await client.connect();

const wallet = Wallet.fromSeed('s████████████████████████████');

const takerGets = {
  currency: 'USD',
  issuer: 'r████████████████████████████',
  value: '100',
};

const takerPays = {
  currency: 'XRP',
  value: '100000000',
};

// オファーの作成
await createOffer(client, wallet, takerGets, takerPays);

client.disconnect();

3. payment.jsの作成

送金を行う汎用的なメソッドを定義します。

// utils/payment.js

// 送金を行う汎用的な関数
export async function sendPayment(client, wallet, amount, destination, options = {}) {
  try {
    const payment = {
      TransactionType: 'Payment',
      Account: wallet.classicAddress,
      Amount: typeof amount === 'object' ? amount : amount.toString(),
      Destination: destination,
    };

    if (options.sendMax !== undefined && options.sendMax !== null) {
      payment.SendMax = typeof options.sendMax === 'object' ? options.sendMax : options.sendMax.toString();
    }

    if (options.paths !== undefined && options.paths !== null) {
      payment.Paths = options.paths;
    }

    const response = await client.submitAndWait(payment, { wallet });
    console.log(`Payment sent from ${wallet.classicAddress} to ${destination}:`, response);
    return response;
  } catch (error) {
    console.error(`Error sending payment from ${wallet.classicAddress} to ${destination}: ${error}`);
    throw error;
  }
}

使用方法

import { Client, Wallet } from 'xrpl';
import { sendPayment } from './utils/payment.js';

...

// クライアントとウォレットの初期化
const client = new Client('wss://s.altnet.rippletest.net:51233');
await client.connect();

const wallet = Wallet.fromSeed('s████████████████████████████');

const amount = {
  currency: 'USD',
  issuer: 'r████████████████████████████',
  value: '10',
};

const destination = 'r████████████████████████████';
const sendMax = '100000000';

// 送金の実行
await sendPayment(client, wallet, amount, destination, {
  sendMax: sendMaxAmount
})

client.disconnect();

4. setAccountFlags.jsの作成

アカウントのリップリング許可を設定する汎用的なメソッドを定義します。

// utils/setAccountFlags.js

// アカウントのフラグを設定する関数
export async function setAccountFlags(
  client,
  wallet,
  setFlag
) {
  try {
    const accountSet = {
      TransactionType: 'AccountSet',
      Account: wallet.classicAddress,
      SetFlag: setFlag,
    };

    const response = await client.submitAndWait(accountSet, { wallet });
    console.log(`Account flags set for ${wallet.classicAddress}:`, response);
    return response;
  } catch (error) {
    console.error(
      `Error setting account flags for ${wallet.classicAddress}: ${error}`
    );
    throw error;
  }
}

使用方法

例えば、アカウントに対してリップリングを許可する場合に使用できます。

import { Client, Wallet, AccountSetAsfFlags } from 'xrpl';
import { setAccountFlags } from './utils/setAccountFlags.js';

...

// クライアントとウォレットの初期化
const client = new Client('wss://s.altnet.rippletest.net:51233');
await client.connect();

const wallet = Wallet.fromSeed('s████████████████████████████');

const setFlag = AccountSetAsfFlags.asfDefaultRipple; // リップリング許可の設定 8

// アカウントフラグの設定
await setAccountFlags(client, wallet, setFlag);

client.disconnect();

5. issueCurrency.jsの作成

トークンを発行する汎用的なメソッドを定義します。

// utils/payment.js

// トークンを発行する関数
export async function issueCurrency(
  client,
  issuerWallet,
  recipientAddress,
  currency,
  amount
) {
  try {
    const payment = {
      TransactionType: 'Payment',
      Account: issuerWallet.classicAddress,
      Amount: {
        currency: currency,
        issuer: issuerWallet.classicAddress,
        value: amount,
      },
      Destination: recipientAddress,
    };
    const response = await client.submitAndWait(payment, {
      wallet: issuerWallet,
    });
    console.log(`Currency issued to ${recipientAddress}:`, response);
    return response;
  } catch (error) {
    console.error(`Error issuing currency to ${recipientAddress}: ${error}`);
    throw error;
  }
}

使用方法

import { Client, Wallet } from 'xrpl';
import { issueCurrency } from './utils/issueCurrency.js';

...

// クライアントとウォレットの初期化
const client = new Client('wss://s.altnet.rippletest.net:51233');
await client.connect();

const issuerWallet = Wallet.fromSeed('s████████████████████████████');
const recipientAddress = 'r████████████████████████████';

const currency = 'USD';
const amount = '1000';

// トークンの発行
await issueCurrency(client, issuerWallet, recipientAddress, currency, amount);

client.disconnect();

まとめ

このように、よく使用する処理を汎用的なメソッド(関数)として定義することで、開発効率を著しく向上できると考えています。

設計については、個人的な思想や考えがあれば独自に変更していくと良いかと思いますが、xrpl.jsで開発を進める際にはぜひ参考にしてみてください。

Discussion