Solana DEV #02: Получение всех транзакций депозита вашего кошелька

Если вы используете кошелек Phantom для оплаты транзакций на блокчейне Solana, вы можете заметить, что каждый раз, когда вы отправляете токены SOL или SPL на другой адрес, эта транзакция записывается и отображается в интерфейсе кошелька Phantom.

Сначала я подумал, что это просто похоже на любые другие данные, получаемые с помощью getProgramAccounts с фильтрацией. Однако, это работает не так.

Выборка подписей и транзакций

Чтобы получить все депозитные транзакции по одному адресу, необходимо получить все подписи по этому адресу с помощью метода getSignaturesForAddress.

const signatureInfos = await connection.getSignaturesForAddress(vaultAddress);
Вход в полноэкранный режим Выйти из полноэкранного режима

А затем отобразите информацию для получения только подписей транзакций

const signatures = signatureInfos.map(sig => sig.signature);
const transactions = await connection.getParsedTransactions(signatures);
Войти в полноэкранный режим Выйти из полноэкранного режима

У этого подхода есть очень большая проблема. Он не позволяет отфильтровать полученные подписи, как это обычно делается с помощью getProgramAccounts. И в этом случае, он будет просто получать большое количество транзакций с вашего адреса, так как ваш адрес имеет другие взаимодействия с кошельком, кроме приема и отправки монет. Чтобы сделать это более эффективным, я стараюсь отфильтровать сигнатуры успеха из возвращаемых данных

const filteredSignatureInfos = signatureInfos.filter(sig => !sig.err && !sig.memo);
Вход в полноэкранный режим Выйти из полноэкранного режима

Но не повезло, если ваш кошелек имеет около 300 или более транзакций, RPC не позволит вам получить монету, так как существует ограничение по скорости. Я не знаю, есть ли другие лучшие подходы, но это тот, который я нашел.

Как улучшить этот подход?

Это может быть неприемлемым ответом, но есть несколько способов улучшить ситуацию.

  • Попытаться отделить хранилище от кошелька. Хранилище будет представлять собой КПК, который использует адрес кошелька в качестве начального. Таким образом, все транзакции, которые включает в себя хранилище, будут связаны только с токенами и родным SOL. Даже самое посещаемое хранилище может содержать всего около 50-100 транзакций.
  • Использование кэш-базы данных, раздела и слушателя событий: Эта техника обычно используется при разработке традиционного бэкенда. Если у вас есть около 300 транзакций для адреса, попробуйте разделить их на более мелкие части: по 50 транзакций на каждую. Кэшируйте эти данные и затем обновляйте базу данных только в случае поступления новых данных (используйте onAccountChange).

Фильтрация транзакций

Есть два типа транзакций, которые вы можете захотеть отфильтровать, чтобы отобразить похожий результат от Phantom: транзакции депозитов Native SOL и транзакции депозитов токенов SPL. Если вы используете getParsedTransactions, как я сделал выше, все данные уже преобразованы в человекочитаемый язык. Необработанные транзакции с помощью getTransactions возвращают только шестнадцатеричные данные. Я написал эти два метода, чтобы вы могли использовать их повторно, это довольно просто, потому что все данные уже разобраны.

// Filter SPL token deposit transaction
isSplTokenDepositTx(tx: any): boolean {
  const ixs = tx.transaction.message.instructions;
  const ix: any = ixs[ixs.length - 1];
  return (
    ix.programId.equals(TOKEN_PROGRAM_ID) &&
    (ix.parsed.type === 'transfer' || ix.parsed.type === 'transferChecked')
  );
}

// Filter Native SOL deposit transaction
isSolDepositTx(tx: any): boolean {
  const ix: any = tx.transaction.message.instructions[0];
  return ix.programId.equals(SYSTEM_PROGRAM_ID) && ix.parsed.type === 'transfer';
}
Вход в полноэкранный режим Выход из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий