Solana DEV #02: 지갑의 모든 Deposit 트랜잭션 검색

팬텀 지갑을 사용하여 솔라나 블록체인의 거래 비용을 지불하는 경우 SOL 또는 SPL 토큰을 다른 주소로 보낼 때마다 해당 거래가 기록되고 팬텀 지갑 인터페이스에 나열된다는 것을 알 수 있습니다.



처음에는 필터링과 함께 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는 속도 제한이 있으므로 가져오기를 허용하지 않습니다. 다른 더 나은 접근 방식이 있는지 모르겠지만 이것이 내가 찾은 것입니다.

접근 방식을 개선하는 방법은 무엇입니까?



이는 수용 가능한 답변이 아닐 수 있지만 사례를 개선할 수 있는 몇 가지 방법이 있습니다.
  • 지갑에서 금고를 분리하려고 합니다. 볼트는 지갑 주소를 시드로 사용하는 PDA가 될 것입니다. 그런 식으로 금고에 포함된 모든 트랜잭션은 토큰 및 기본 SOL에만 관련됩니다. 트래픽이 가장 많은 저장소도 약 50-100개의 트랜잭션만 가질 수 있습니다.
  • 캐시 데이터베이스, 파티션 및 이벤트 리스너 사용: 이 기술은 일반적으로 기존 백엔드 개발에서 사용됩니다. 주소에 대해 약 300개의 트랜잭션이 있는 경우 각 트랜잭션을 50개의 트랜잭션으로 더 작은 부분으로 분할하십시오. 해당 데이터를 캐시한 다음 새 데이터가 들어오는 경우에만 데이터베이스를 업데이트합니다(onAccountChange 사용).

  • 트랜잭션 필터링



    Phantom에서 유사한 결과를 표시하기 위해 가져올 수 있는 두 가지 유형의 트랜잭션이 있습니다. 기본 SOL 입금 트랜잭션과 SPL 토큰 입금 트랜잭션입니다. 위에서 했던 것처럼 getParsedTransactions를 사용하면 이미 모든 데이터가 사람이 읽을 수 있는 언어로 변환되어 있습니다. getTransactions를 사용하는 원시 트랜잭션은 16진수 데이터만 반환합니다. 재사용할 수 있도록 이 두 가지 방법을 작성했습니다. 모든 데이터가 이미 구문 분석되었기 때문에 매우 간단합니다.

    // 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';
    }
    

    좋은 웹페이지 즐겨찾기