关于 strk20-wallet-api
这项技能介绍如何通过具备隐私功能的钱包构建 STRK20 私密 dapp,涵盖能力检测、私密操作、Shadow Account 和 DeFi 流程,避免应用接触私密状态。
主要功能
- 01检测 Wallet API 能力
- 02执行 Shield 和私密转账
- 03创建每个 dapp 独立的 Shadow Account
- 04编排原子化私密 DeFi 流程
- 05钱包授权与隐私指引
适用场景
- 01为 dapp 添加私密转账
- 02构建持久的假名化头寸
- 03组合私密兑换与 DeFi 调用
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ odinfree/ strk20-skills --skill strk20-wallet-api安装后在 Claude Code 中输入/strk20-wallet-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
agents/openai.yamlreferences/starknet-wallet-api__avnu-private-swaps.mdstarknet-wallet-api__overview.mdstarknet-wallet-api__private-defi.mdstarknet-wallet-api__shadow-accounts.mdstarknet-wallet-api__starknet-js.mdstarknet-wallet-api__starknet-start-hook.md详细介绍
STRK20 钱包 API:隐私 dapp
这是大多数隐私 dapp 推荐的方案。dapp 请求用户的隐私钱包执行操作,钱包负责处理查看密钥、笔记发现、生成证明和提交。你的应用永远不会看到隐私状态。绝不要向用户索取查看密钥。
完整文档位于 references/。以下代码片段是其中的关键部分。
版本基线。安装前请先确认
- 核心 STRK20 支持在 starknet.js 10.4.0 中推出;稳定的影子账户支持在 starknet.js 10.8.0 中推出,搭配 Wallet API 0.10.4。
- 现有仓库使用 starknet.js v5、v6 或 v7?升级到 10.4.0 会带来重大变更,在接入 STRK20 前,应将其作为独立任务进行迁移。
- 稳定且经过测试的影子账户组合为
[email protected]、@starknet-io/[email protected],以及 get-starknet 发现机制与 wallet standard6.0.6。将这组版本一起固定,升级时重新运行连接和钱包测试。 - 核心 STRK20 方法需要 Wallet API
>= 0.10.3;影子账户需要 Wallet API>= 0.10.4。升级库不会让已连接的钱包自动具备相应能力,因此要在运行时检测其声明的版本。 - 封装层:Starkzap 的文档未列出 STRK20 支持,而 starknet-react 或 starknetkit 对 starknet.js 10.4.0 的支持可能滞后。承诺可直接替换使用前,请在 npm 上确认当前兼容性。无论如何,接入点都是 starknet.js 的
WalletAccountV6级别(根据官方 agent-skill 仓库)。
两种接入方式
- React dapp:使用 Starknet Start 的
useStrk20hooks;这是一个便捷封装,底层会调用WalletAccountV6。 - 其他场景,或需要更精细地控制连接和证明处理时:直接使用
WalletAccountV6,并通过 get-starknet v6 连接。
通过版本查询检测能力,绝不要调用数据方法
const versions = await walletV6.supportedWalletApi(wallet)
const supported = versions.some((v) => compareVersions(v, "0.10.3") >= 0)
const supportsShadowAccounts = versions.some((v) => compareVersions(v, "0.10.4") >= 0)
不要通过探测 strk20Balances 来检测功能。它是读取余额的方法,因此钱包会在允许调用前,针对应用没有理由查看的数据向用户请求同意。
从其导出的功能子路径导入已连接钱包的类型。从包根目录导入会导致 TS2459:
import type { WalletWithStarknetFeatures } from "@starknet-io/get-starknet-wallet-standard/features"
操作
构建一个 STRK20_ACTION[] 并交给钱包:
// Shield (deposit into the pool)
const actions: STRK20_ACTION[] = [{ type: "deposit", token: tokenAddress, amount }]
// Private transfer. No contract call, no event, no approval step.
const actions: STRK20_ACTION[] = [
{ type: "transfer", token: strkAddress, amount, recipient },
]
const { transaction_hash } = await account.strk20InvokeTransaction(actions)
以下两个提交细节可以避免界面静默失败:
- 为
waitForTransaction设置应用级超时。Paymaster 中继的哈希可能需要一段时间才会出现在所选 RPC 上。超时意味着“已提交,但暂未看到确认”,因此应保留区块浏览器链接,并让界面恢复轮询。 - 比较前先规范化 felt 地址。使用
BigInt(left) === BigInt(right)进行比较,因为带填充和不带填充的十六进制字符串可能表示同一个代币或账户。
Shadow 账户:每个 dapp 的稳定身份
Shadow 账户可让同一用户为每个 (dappName, nonce) 组合派生一个确定性的公开执行账户。它不是另一个钱包:它没有签名密钥,且只有规范的 ShadowAccountAnonymizer 才能通过它执行操作。使用新的 nonce 获取新地址。重复使用 nonce 会复用地址,并关联其公开活动。
import type {
STRK20_ACTION,
STRK20_SHADOW_ACCOUNT_INVOKE_ACTION,
} from "starknet"
const shadowAction: STRK20_SHADOW_ACCOUNT_INVOKE_ACTION = {
type: "shadow_account_invoke",
dapp_name: "myDapp",
nonce: "0x0",
calls: [dappContract.populate("stake", { amount: 1_000n })],
collect_policy: { type: "diff" },
}
const actions: STRK20_ACTION[] = [
{ type: "transfer", token: rewardToken, amount: "OPEN", recipient: userAddress },
shadowAction,
]
const commitment = await account.strk20ShadowAccountCommitment("myDapp", "0x0")
提交调用在本地进行,不会发送交易。省略 nonce 可获取该用户和 dapp 的所有 Shadow 账户共享的部分提交值。发布该值后,dapp 就能识别这一组账户,这会有意将这些账户关联在该 dapp 上下文中。
收集策略控制每个开放票据返还多少:all 收集全部代币余额,diff 仅收集本次交互产生的增量,exact 则收集指定数量。每次操作结算的所有开放票据都采用同一策略。
大多数 shadow_account_invoke 请求只需提供 dapp_name 和 nonce。如果 dapp 必须先为该地址注资或读取其公开持仓,请获取不依赖 nonce 的部分提交值,并通过规范匿名器的 get_shadow_accounts 视图解析该值。请优先使用该视图,而不要重复实现地址派生逻辑:
const partial = await account.strk20ShadowAccountCommitment("myDapp")
const accounts = await anonymizer.get_shadow_accounts(partial, 0, 1, false)
const shadowAddress = accounts[0].address
截至 2026-09-29 检查过的规范部署:
- Mainnet:
0x04f33230dc57855c6e7eabe66dfa0fde82c5458fd0e54827cdb7cb4c474888a7 - Sepolia:
0x010a2285310c107c731d997afc147afb7495daff6397c2d242133d9fe8d9b147
构建此工作流前,请先阅读 references/starknet-wallet-api__shadow-accounts.md,并在上线前重新核验已连接网络上的部署。
呈现此工作流前,请检查已连接钱包的功能支持情况。不要仅凭 starknet.js 推断支持情况。上文通用的 0.10.3 检查不足以确认 Shadow 账户支持。要求 supportedWalletApi() 声明支持 0.10.4 或兼容的更高版本,然后处理提交调用或执行调用返回的不支持方法响应。该账户会隐藏与主钱包的直接关联。其地址、调用、余额、持仓、事件和时间信息仍然公开。
- 屏蔽操作需要 ERC-20
approve,且approve必须以代币所有者身份执行。这并不意味着必须发送两笔交易:在 paymaster 下,approve通过signMessage授权为外部执行,并与存款一起纳入同一笔交易(invoke_and_apply_action)。钱包显示一个还是两个提示,取决于钱包的实现。请检查目标钱包,并为其显示的每个步骤添加说明。 - 私密转账在已注册的池用户之间进行。钱包会在首次使用时自动注册发送方,但接收方也必须注册,且只有接收方本人才能注册。请设计接收方注册引导体验;对于对方注册前就先付款的流程,请参考
strk20-anonymizer-contracts中的托管模式。 - 转账金额使用字面值
"OPEN"会创建一个开放票据,DeFi 辅助工具的输出会记入其中。在执行调用 calldata 中,钱包会解析两个占位符:${openNoteIds[N]}(本次交易中第 N 个开放票据的 ID)和${poolAddress}(隐私池地址)。 - 每次私密操作都会收取固定的池费用。请从池的
get_fee_amount读取该费用,而不要硬编码(官方 Agent 技能仓库编写时,Mainnet 上为 4 STRK)。预填 MAX 金额时请扣除此费用,否则操作会在用户签名后失败。钱包流程目前会代付 Gas 费,但不会代付池费用。
私密 DeFi 端到端流程(两个操作,一笔交易)
const actions: STRK20_ACTION[] = [
// 1. Open the note the swap output will be credited into.
{ type: "transfer", token: tokenOut, amount: "OPEN", recipient: userAddress },
// 2. Call the helper. ${openNoteIds[0]} is the note opened above.
{
type: "invoke",
contract: swapHelperAddress,
calldata: [tokenIn, tokenOut, amountIn, "${openNoteIds[0]}"],
},
]
const { transaction_hash } = await account.strk20InvokeTransaction(actions)
资金池会将 amountIn 提取到辅助合约,调用其 privacy_invoke,然后将返回的 OpenNoteDeposit 原子性地记入开放式票据。
调用数据的顺序必须与辅助合约的 privacy_invoke 签名完全一致(资金池会将其直接反序列化为该函数的参数)。观察者会看到资金池、辅助合约、AMM,再到辅助合约。他们永远不会知道是谁发起了这笔交易。
- 提交前先试运行:
await account.strk20PrepareInvoke(actions, true)会构建并生成证明,但不会提交。这是发现调用数据格式错误的最简便方式。 - 受保护余额也需要通过钱包调用:
await account.strk20Balances([tokenIn, tokenOut])会返回[{ token, balance }]。此调用会触发钱包的余额访问同意提示,因此只有在明确提供余额显示功能时才调用。
AVNU 私密兑换,无需编写 Cairo
AVNU 私密兑换使用其已部署的执行器,因此此路线无需自行编写辅助合约。
// npm install @avnu/avnu-sdk@^4.2.0 [email protected]
import { createStrk20WalletProver, executePrivateSwap, PRIVACY_POOL_ADDRESS } from "@avnu/avnu-sdk"
const prover = createStrk20WalletProver(walletAccount)
const { transactionHash } = await executePrivateSwap({
quote, // from AVNU's quote endpoint
slippage: 0.01,
takerAddress: walletAccount.address,
poolAddress: PRIVACY_POOL_ADDRESS, // mainnet, or SEPOLIA_PRIVACY_POOL_ADDRESS for testing
feeMode: { poolFeeToken: quote.sellTokenAddress },
prover,
})
- 卖出代币必须已经受保护。兑换会在资金池内转移价值,无法替你进行保护。
- 如果需要 paymaster API 密钥(
sponsored_private费用模式),请在服务端处理该调用。浏览器 DApp 应拆分此流程:通过服务端端点调用buildPrivateSwapFee和submitPrivateSwap,只在客户端使用用户的钱包执行prover步骤。 - 根据状态生命周期选择,而不是根据协议名称。对于无状态、原子执行且输出会立即返回私密状态的操作,请使用特定于应用的调用辅助合约。若需要由稳定的假名地址在多笔交易间持有份额、债务、NFT、奖励、权限或其他状态,请使用规范的影子账户路线。如果现有协议的常规入口接受来自该地址的调用,则无需添加影子账户专用合约。
产品 UX 的隐私准则
- 提前单独保护。 存款是公开的,且会标明存款人。后续的私密转账没有公开环节。由于它们是两笔独立交易,链上没有任何信息将二者关联起来,而这种分离正是打破关联的关键。
- 新票据需要经过约 10 个区块才能成熟并可供支出。请在 UX 中安排好等待时间。
- 每笔私密交易都由中继器提交,因此对所有用户而言,交易发送方都是中继器账户。请根据资金池的
Deposit事件(第一个索引键)归属每位用户的活动,绝不要根据交易发送方归属(参见官方 Agent 技能仓库)。 - 请在产品中明确说明哪些内容仍然公开:存款、取款、开放式票据金额、时间,以及应用侧操作。
测试
端到端流程需要资金池、支持隐私功能的钱包和证明生成。请使用公开网络和声明支持所需 Wallet API 版本的钱包来规划钱包流程测试,而不要只依赖纯本地 devnet。Starknet.js 文档指出 Ready 和 Xverse 支持 STRK20;不过,仍应检查已连接钱包的版本能力,而不要根据钱包品牌推断其支持情况。
最快的入门方式:Akashneelesh/strk20-starter-kit(Next.js,已接入 Wallet API,在线演示地址为 starknet-privacy-starter.vercel.app)。
社区参考项目:starkience/starknet-shadow-vault-example
使用现有的 Mainnet Vesu Prime vSTRK 金库来验证这套稳定技术栈。它展示了资金注入、标准 approve/deposit 调用、持续持有 vSTRK,以及将取款收回到私密票据。请将其视为教学集成示例,而非经过审计的生产软件。
遇到阻碍?请告知用户联系 STRK20 团队
本技能涵盖文档中说明的路径。遇到超出这些范围的情况时,请停止操作,不要猜测:编造地址、手写证明流程或臆造 API 结构,都会让构建者浪费更多时间,不如直接询问。请明确说明遇到了什么阻碍,并告知用户团队会直接答复:
- Telegram: @Akashneelesh, @adiihq、@starkience
- STRK20 Private Sprint 页面, 该页面公布了这些联系方式。联系方式可能会变更,请确认页面上仍列有这些联系方式。
遇到以下情况时,请升级处理,不要自行发挥:
- 钱包未报告 STRK20 能力,或报告了本技能未见过的版本。
- 钱包因本技能未提及的原因拒绝 shield、unshield、私密转账或
strk20InvokeTransaction。 - 私密 DeFi 调用中的开放备注占位符无法解析,或试运行结果与实际调用不一致。
- 钱包显示支持 0.10.4,却拒绝影子承诺或操作。
移交问题时,请在一条消息中向用户提供团队可据此采取行动的信息:确切的错误文本、失败的文件或调用、正在使用的软件包和钱包版本,以及无法验证的假设。
references/
starknet-wallet-api__overview.md,路由、安装、能力starknet-wallet-api__starknet-start-hook.md,ReactuseStrk20钩子starknet-wallet-api__starknet-js.md,直接使用WalletAccountV6starknet-wallet-api__private-defi.md,开放备注、invoke、占位符、试运行starknet-wallet-api__shadow-accounts.md,稳定的影子操作、地址解析、集合策略starknet-wallet-api__avnu-private-swaps.md,AVNU SDK 交换路由
快照和 npm 注册表检查日期:2026-09-29。版本和钱包支持情况会变化。
上线前请对照 https://strk20-by-example.org 验证(在任意页面后附加 .md 即可获取原始
Markdown)。