Solana Geyser gRPC - 过滤器

Solana Stream SDK 作为开源软件提供。更多详情请访问以下 GitHub 仓库。
gRPC 过滤器概述
Solana Geyser gRPC 使用过滤器高效获取您感兴趣的数据,如特定账户、程序、交易、slot 和区块。
以下是使用 Solana Stream SDK 的 TypeScript 示例,清楚地说明了每个过滤器的具体作用。使用 Rust 时,过滤器的结构和含义完全相同。
各过滤器的作用和示例
订阅账户
订阅特定账户的实时更新。以下示例以 Confirmed 确认级别订阅 SOL-USDC OpenBook 账户:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: { slots: {} },
accounts: {
'wsol/usdc': {
account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.CONFIRMED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: { slots: {} },
accounts: {
'wsol/usdc': {
account: ['8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.CONFIRMED,
}"wsol/usdc"是客户端自定义的标签。- 账户、程序、区块和 slot 的多个过滤器可以在单个 JSON 请求中组合使用。
使用 account_data_slice 订阅账户
此示例演示仅检索账户数据的特定部分。不获取 USDC 代币账户的全部数据(165 字节),而是从偏移量 32 开始检索 40 字节。此范围包含所有者和 lamports 余额等信息。
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {
usdc: {
owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
filters: [
{
tokenAccountState: true,
},
{
memcmp: {
offset: 0,
data: {
base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
},
},
},
],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
entry: {},
commitment: CommitmentLevel.CONFIRMED,
accountsDataSlice: [{ offset: 32, length: 40 }],
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {
usdc: {
owner: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
filters: [
{
tokenAccountState: true,
},
{
memcmp: {
offset: 0,
data: {
base58: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
},
},
},
],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
entry: {},
commitment: CommitmentLevel.CONFIRMED,
accountsDataSlice: [{ offset: 32, length: 40 }],
}订阅程序
此示例演示订阅与特定程序关联的账户更新。
以下以
Processed 确认级别订阅 Solend 程序拥有的账户更新。typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
solend: {
owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
solend: {
owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}"solend"是客户端可以自由设置的自定义标签。- 要订阅多个程序,请参阅下一节"订阅多个程序"。
订阅多个程序
此示例演示如何同时订阅与多个程序关联的账户更新。
以下示例订阅 Solend 和 Serum 程序拥有的账户更新。
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
programs: {
owner: [
'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo',
'9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
programs: {
owner: [
'So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo',
'9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}如果您希望为每个程序分配单独的标签,请使用以下方式:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
solend: {
owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
serum: {
owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {
solend: {
owner: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
serum: {
owner: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
},
},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅所有已最终确认的非投票且未失败的交易
此示例演示以
Finalized 确认级别订阅所有交易,排除投票交易和失败交易。typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
alltxs: {
vote: false,
failed: false,
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.FINALIZED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
alltxs: {
vote: false,
failed: false,
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.FINALIZED,
}vote: false排除投票交易。failed: false排除失败交易。- 如果字段留空,将检索所有交易。
- 指定多个字段时,它们以 AND 条件运行。
订阅涉及特定账户的非投票交易
此示例演示订阅涉及特定账户但排除投票交易的交易。
以下示例订阅涉及 Serum 程序关联账户的非投票交易。
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
vote: false,
accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
vote: false,
accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅排除特定账户的交易
此示例演示订阅排除涉及特定账户的交易。
以下示例检索排除 Serum 和 Tokenkeg 程序拥有的任何账户的交易。
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
accountExclude: [
'9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
accountExclude: [
'9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin',
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA',
],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅涉及特定账户并排除某些账户的交易
此示例演示订阅涉及某些账户的交易,同时明确排除其他指定账户。
以下示例订阅涉及 Serum 账户的交易,但排除指定账户:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
slots: {},
},
accounts: {},
transactions: {
serum: {
accountInclude: ['9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin'],
accountExclude: ['9wFFyRfZBsuAha4YcuxcXLKwMxJR43S7fPfQLusDBzvT'],
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅交易签名
此示例演示订阅特定交易签名的实时更新,直到它达到
Confirmed 或 Finalized 状态。typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {
sign: {
signature:
'5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {
sign: {
signature:
'5rp2hL9b6kexex11Mugfs3vfU9GhieKruj4CkFFSnu52WLxiGn4VcLLwsB62XURhMmT1j4CZiXT6FFtYbXsLq2Zs',
},
},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅 slot
此示例演示订阅传入 slot 的通知。除了分配自定义标签名称外,无需其他详细信息:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
incoming_slots: {},
},
accounts: {},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {
incoming_slots: {},
},
accounts: {},
transactions: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅区块
订阅所有生成区块的实时更新。默认情况下,将检索区块内的所有交易:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}排除交易,仅检索更新的账户信息:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {
includeTransactions: false,
includeAccounts: true,
},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {
includeTransactions: false,
includeAccounts: true,
},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}仅检索涉及特定账户的交易/账户:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {
accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {
blocks: {
accountInclude: ['So1endDq2YkqhipRh3WViPa8hdiSpxWy6z3Z6tMCpAo'],
},
},
blocksMeta: {},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}订阅区块元数据
仅订阅区块处理时的区块元数据通知。不包含详细的交易数据。
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {},
blocksMeta: {
blockmetadata: {},
},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
const request = {
slots: {},
accounts: {},
transactions: {},
blocks: {},
blocksMeta: {
blockmetadata: {},
},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
}管理确认级别
Solana Geyser gRPC 流默认使用
Processed 确认级别。您可以指定更高的确认级别,如
Confirmed 或 Finalized。在这些情况下,Geyser 会缓冲数据并在达到指定的确认级别后发送通知。为获得最佳性能,建议在客户端管理确认级别。
以下是指定确认级别的方法:
typescript
import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
enum CommitmentLevel {
PROCESSED = 0,
CONFIRMED = 1,
FINALIZED = 2,
}import { CommitmentLevel } from '@validators-dao/solana-stream-sdk'
enum CommitmentLevel {
PROCESSED = 0,
CONFIRMED = 1,
FINALIZED = 2,
}PROCESSED:处理后的即时数据。检索速度快,但尚未确认。CONFIRMED:经集群确认的数据,提供更高的确定性。FINALIZED:完全最终确认的数据,没有重组风险。
使用 Processed 的优势
Processed 确认级别的主要优势是即时交易检索,能够快速进行客户端处理。客户端随后可以检测到向 Confirmed 或 Finalized 的转换,提供快速响应能力。如何管理 Confirmed 和 Finalized
使用
Confirmed 或 Finalized 级别时,应按 slot 缓冲事件(交易或账户更新)。按 slot 缓冲事件,订阅 slot 通知,并在特定 slot 达到所需确认级别(
Confirmed 或 Finalized)后从缓冲区释放事件。事件最初会在 slot 达到
Confirmed 或 Finalized 之前接收。Finalized 的特殊之处
由于 Solana Geyser 规范,并非所有 slot 都会收到明确的最终确认通知。因此,当您收到某个 slot 的最终确认通知时,必须将所有祖先 slot 也视为已最终确认,即使没有收到明确的通知。
具体来说,收到最终确认通知后,追溯地将所有祖先 slot 视为已最终确认。