一个能正确处理经典 SPL 代币的机器人,不会"部分地"处理 Token-2022。★它在一些代币上完全正常,在另一些上完全失败,中间没有过渡。★
这其实是好消息 —— 因为它意味着这次集成是一份有限的清单,而不是一项持续的税。
五处硬编码的假设
每一个只支持经典代币的机器人都藏着这些,而且通常没意识到:
TOKEN_PROGRAM_ID // ★被当成常量★
getAssociatedTokenAddress(mint, owner) // ★漏了 program ID★
{ dataSize: 165 } // ★假设了账户大小★
minOut = expected * (1 - slippage) // ★假设全额到账★
createTransferInstruction(...) // ★只支持经典的构造器★
★每一处在遇到 Token-2022 的 mint 之前都完美工作,然后以一种不会点名这个假设的方式失败。★
按这个顺序修
顺序很重要 —— 乱序修会产出一个以令人困惑的方式半可用的机器人。
1. 从 mint 解析出 program ID。 后面每一步都依赖它可用。
async function resolveToken(connection, mint) {
const info = await connection.getAccountInfo(mint);
if (!info) throw new Error("mint 不存在");
return { programId: info.owner, is2022: info.owner.equals(TOKEN_2022_PROGRAM_ID) };
}
★缓存它 —— 一个 mint 的所属程序永不改变。★ 在你追踪代币的每一处,都把它和 mint 地址存在一起。
2. 把它贯穿到每一次推导和每一个构造器。
const ata = await getAssociatedTokenAddress(mint, owner, false, programId);
const ix = createTransferInstruction(src, dst, owner, amount, [], programId);
★省略这个参数会默认成经典程序★ —— 这就是为什么这个失败在经典代币上完全不可见、在 Token-2022 上是全面的。
如果你的 Token-2022 支持已经完整、交易还是会错过,免费领个 BoltTx key 改一行就能测测提交路径。
3. 两个程序都查余额。
const [a, b] = await Promise.all([
connection.getParsedTokenAccountsByOwner(wallet, { programId: TOKEN_PROGRAM_ID }),
connection.getParsedTokenAccountsByOwner(wallet, { programId: TOKEN_2022_PROGRAM_ID }),
]);
4. 交易之前先筛查扩展。 跳过不可转让和永久委托方;为转账费、hook、默认冻结做适配。
5. 最后再改费用算法。 它依赖第 4 步已经读到了配置。
★在第 1 步之前做第 5 步是常见的错误★ —— 你没法为一个还没解析出程序的 mint 计算转账费。
它在延迟上花你多少
对狙击手来说,老实的账是:
多一次账户读取 —— 就是那个 mint,它在一次读取里同时给你 program ID 和扩展数据。★而你多半本来就要为 decimals 读它。★
经典代币不额外花任何时间。 owner 检查立刻短路,所以大多数代币只花你一次比较。
带 hook 的代币要模拟 —— 那是真的贵,也正是这类代币在速度敏感的策略里通常值得跳过的原因。
★这次集成不会拖慢你现有的流程。它加的是一个大多数代币不会走进去的分支。★
测试上的难题
你没法在 devnet 上拿真实代币验证这件事,因为你在乎的那些代币在那里不存在。
行得通的做法:
// ★自己造带各种扩展的测试 mint。★
await createMint(connection, payer, authority, null, 9,
Keypair.generate(), undefined, TOKEN_2022_PROGRAM_ID);
你声称支持哪个扩展,就为它造一个 mint,然后拿完整交易路径跑一遍。★一个从没对着带费用的 mint 执行过的机器人,它的费用算法就是未经测试的★ —— 不管写得多仔细。
要测卖出,不只是买入。 不可转让代币和选择性 revert 的 hook,在买入时都看起来正常、在退出时才失败 —— 而那是在生产环境发现代价最高的方向。
什么完全没变
值得说清楚,因为它界定了工作量:
- ★交易结构、签名、1232 字节上限★
- ★blockhash 处理、过期、重试行为★
- ★compute budget 指令和手续费推导★
- 前 165 字节的账户布局
- ★关于提交和上链的一切★
★Token-2022 是代币层的变化,不是交易层的。★ 你的重试循环、手续费策略、提交路径都不用动 —— 这就是这次集成是有限的原因。
一份验收清单
□ program ID 从 mint 的 owner 解析,不是假设
□ program ID 传给每一次 ATA 推导
□ program ID 传给每一个指令构造器
□ 余额查询覆盖两个程序
□ ★dataSize 过滤器不假设 165★
□ 交易前筛查扩展
□ ★转账费在滑点之前减掉★
□ hook 账户用异步构造器组装
□ 不可转让、永久委托方直接拒绝
□ ★卖出路径测过,不只是买入★
□ 租金按实际账户大小计算
★带星的几行是会静默失败的。★ 其余的会产出一个大致指向问题的错误。
上链应该是什么水平
我们投递节点上的真实交易:中位确认 336 毫秒 —— 不到一个 slot。
★Token-2022 支持改变的是你的交易正不正确,不是它多快落块。★ 这是两个独立的问题、有各自的修法,而一笔正确的交易仍然要和其它交易一样争夺收录。
BoltTx 在这里的位置
我们负责提交,而 Token-2022 完全没有改变这一块。
提交走我们自建的四区域投递节点,带 SWQoS 路由,不暴露公共 mempool —— 交易在落块之前、传输途中观察不到。你的指令引用经典还是 2022 代币程序,对我们没有区别 —— 我们传输你签好的字节。
你在本地签名。我们不托管资金、不代签、不修改交易内容。tip 带在交易里、从你自己的钱包链上支付,交易失败时跟着一起 revert —— 这是 Solana 原子交易的机制决定的。只有到达链上的交易才计费。
免费领 API key,没有月费:
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");
常见问题
怎么给现有机器人加 Token-2022 支持? 从 mint 的 owner 解析 program ID、把它贯穿到每一次推导和构造器、两个程序都查余额、筛查扩展,最后调整费用算法。顺序很重要。
经典机器人遇到 Token-2022 代币时最先坏在哪?
通常是 ATA 推导,因为 program ID 是推导的一部分。你会为一个存在于另一个地址的账户拿到 AccountNotFound。
需要重写我的重试和手续费逻辑吗? 不需要。Token-2022 是代币层的变化。 交易结构、blockhash 处理、重试、compute budget 和提交全都不变。
Token-2022 支持会增加多少延迟? 几乎没有。那次 mint 读取在一次请求里同时给你 program ID 和扩展数据,而经典代币在 owner 比较处就短路了。
怎么测试 Token-2022 的处理? 在 devnet 上自己造测试 mint,你支持哪个扩展就造一个,然后跑完整交易路径。带这些扩展的真实代币在 devnet 上不存在。
为什么必须专门测卖出路径? 因为不可转让代币和选择性 revert 的 hook,在买入时都成功、在退出时才失败。只测买入,会把最贵的那种失败留到生产环境。
该支持 transfer hook 吗? 只有当 hook 程序可验证、且双向模拟都干净时才该。对速度敏感的策略,跳过带 hook 的代币通常是更划算的取舍。
哪些扩展该直接拒绝? 不可转让和永久委托方。 一个让你卖不掉,另一个让第三方能拿走你的仓位,两者都没法靠更好的代码解决。
加了 Token-2022 之后,余额查询为什么还是漏代币? 你多半还在只做一次查询。没有合并调用,两个 program ID 需要各查一次,再把结果合并。
需要改我的 dataSize 过滤器吗? 如果它假设了 165 字节,需要。带扩展的账户更大,所以精确大小的过滤会静默排除每一个带扩展的 Token-2022 账户。
滑点里怎么处理转账费? 在套用容忍度之前把费用从预期输出里减掉。 反过来做,会在费用超过滑点时确定性地 revert。
该按 mint 缓存 program ID 吗? 该,而且可以永久缓存。所属程序永不改变,所以它属于你追踪代币的那个结构,和 decimals 放在一起。
如果聚合器帮我处理了 Token-2022 呢? 用一笔小额交易验证,不要假设。 支持程度因协议和扩展而异,transfer hook 尤其需要显式处理。
Token-2022 影响交易体积吗? 间接影响。带 hook 的代币会加账户、每个 32 字节,可能把一条本来装得下的多跳路由顶出 1232 字节上限。
到底值不值得支持 Token-2022? 取决于你交易什么。如果你的目标平台上新用它,值得。 如果不用,干净地筛掉这类代币也是一个有效的替代方案。
最小可用的 Token-2022 支持是什么? 解析 program ID、把它贯穿下去、两个程序都查,并拒绝任何带有你尚未实现的扩展的 mint。这样是安全的,尽管不完整。