dflow-spot-trading
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDFlow Spot Trading
DFlow 现货交易
Swap any pair of Solana tokens via DFlow. Imperative trades (the default) settle synchronously in one transaction; declarative trades are opt-in for users who explicitly want better execution.
通过DFlow交换任意一对Solana代币。命令式交易(默认方式)在单个交易中同步结算;声明式交易为明确追求更优执行效果的用户提供可选方案。
Prerequisites
前提条件
- DFlow docs MCP () — install per the repo README. This skill is the recipe; the MCP is the reference. Look up endpoint shapes, parameter details, error codes, and anything else field-level via
https://pond.dflow.net/mcp/search_d_flow— don't guess.query_docs_filesystem_d_flow - CLI (optional, for command-line/agent use) — install per the repo README.
dflow
- DFlow文档MCP()——按照仓库README安装。本技能是操作指南,MCP是参考资料。通过
https://pond.dflow.net/mcp/search_d_flow查询端点结构、参数细节、错误代码及其他字段级信息——请勿猜测。query_docs_filesystem_d_flow - CLI(可选,用于命令行/Agent场景)——按照仓库README安装。
dflow
Choose your surface
选择操作方式
- CLI — command line, scripts, local agents. Manages keys, signs, broadcasts.
- API — web/mobile apps, backends, automations with their own wallet/signer. Browser apps must proxy HTTP through their backend (the Trading API serves no CORS).
If unclear, ask once: "From the command line, or wired into an app?"
- CLI——命令行、脚本、本地Agent。管理密钥、签名、广播交易。
- API——Web/移动应用、后端、拥有独立钱包/签名者的自动化流程。浏览器应用必须通过后端代理HTTP请求(Trading API不支持CORS)。
若不确定,可询问一次:“是通过命令行操作,还是集成到应用中?”
Workflows
操作流程
Quote (read-only)
报价(只读)
- CLI:
dflow quote <atomic-amount> <FROM> <TO> - API: doubles as a quote — including without a
GET /order, in which case it returns all price fields with no transaction attached. Use this for live-quote UIs before the user has connected a wallet. Don't reach foruserPublicKeyseparately; it's the older surface and the docs redirect back to/quote./order
- CLI:
dflow quote <atomic-amount> <FROM> <TO> - API:可兼作报价接口——即使不传入
GET /order,此时会返回所有价格字段,且不附带交易信息。可用于用户连接钱包前的实时报价UI。无需单独调用userPublicKey接口;该接口为旧版,文档会重定向至/quote。/order
Trade — imperative /order
(the default)
/order交易——命令式/order
(默认方式)
/orderSingle round-trip: get a quote and a signed-ready together; sign, submit, confirm. Fully synchronous. Works with all SPL + Token-2022 mints.
VersionedTransaction-
CLI:(add
dflow trade <atomic-amount> <FROM> <TO>for agents/scripts that need to block until confirmed).--confirm -
API:, deserialize
GET /order?userPublicKey=&inputMint=&outputMint=&amount=(base64) →transaction, sign + broadcast, confirm against the blockhash DFlow signed with. Two broadcast idioms — pick the one that matches your context:VersionedTransaction- Browser wallet-adapter app (the default for UIs). . The wallet signs and broadcasts through its own RPC — your
const sig = await wallet.sendTransaction(tx, connection)only needs to serve reads (connection).confirmTransaction - Node script / server-side signing with a . Two-step:
Keypair→tx.sign([keypair]). Your RPC is what broadcasts; a public endpoint will 403.connection.sendRawTransaction(tx.serialize())
The full browser-adapter happy path, end to end: - Browser wallet-adapter app (the default for UIs).
ts
const { transaction, lastValidBlockHeight } = await fetch("/api/order?...").then(r => r.json());
const tx = VersionedTransaction.deserialize(Buffer.from(transaction, "base64"));
const sig = await sendTransaction(tx, connection); // wallet's RPC
await connection.confirmTransaction( // app's RPC (reads only)
{ signature: sig, blockhash: tx.message.recentBlockhash, lastValidBlockHeight },
"confirmed",
);Where each response field goes (don't re-derive these locally — DFlow owns the authoritative value):
/order- (base64) →
transaction→VersionedTransaction.deserialize(browser) orwallet.sendTransaction(Node).connection.sendRawTransaction - →
lastValidBlockHeight, paired withconnection.confirmTransactionfrom the deserialized tx. Never a freshtx.message.recentBlockhash(see Gotchas).getLatestBlockhash - /
inAmount/outAmount/otherAmountThreshold/priceImpactPct→ display.slippageBps - /
prioritizationFeeLamports→ echo / logging. The server-resolved priority-fee choice afterprioritizationTyperesolution."auto" - → logging / staleness checks.
contextSlot - → optional display / debugging.
routePlan
Fields marked "Specified if and only if the request included the user's public key" in the OpenAPI (, , , , ) are absent on quote-only calls — check before using.
transactionlastValidBlockHeightcomputeUnitLimitprioritizationFeeLamportsaddressLookupTablesFull runnable example (server-side variant): (links to the DFlow Cookbook Repo). Field-level schema details via the docs MCP.
Keypair/build/recipes/trading/imperative-trade单次往返:同时获取报价和已准备好签名的;签名、提交、确认。完全同步。支持所有SPL + Token-2022代币铸造地址。
VersionedTransaction-
CLI:(若Agent/脚本需要阻塞直到交易确认,添加
dflow trade <atomic-amount> <FROM> <TO>参数)。--confirm -
API:,反序列化
GET /order?userPublicKey=&inputMint=&outputMint=&amount=(base64格式)为transaction,签名并广播,根据DFlow签名使用的区块哈希进行确认。两种广播方式——根据场景选择:VersionedTransaction- 浏览器钱包适配器应用(UI默认方式):。钱包会通过自身RPC完成签名并广播——你的
const sig = await wallet.sendTransaction(tx, connection)仅需处理读操作(connection)。confirmTransaction - Node脚本/服务器端使用签名:分两步:
Keypair→tx.sign([keypair])。广播由你的RPC完成;公共端点会返回403错误。connection.sendRawTransaction(tx.serialize())
浏览器适配器完整流程示例: - 浏览器钱包适配器应用(UI默认方式):
ts
const { transaction, lastValidBlockHeight } = await fetch("/api/order?...").then(r => r.json());
const tx = VersionedTransaction.deserialize(Buffer.from(transaction, "base64"));
const sig = await sendTransaction(tx, connection); // 钱包的RPC
await connection.confirmTransaction( // 应用的RPC(仅读)
{ signature: sig, blockhash: tx.message.recentBlockhash, lastValidBlockHeight },
"confirmed",
);/order- (base64)→
transaction→VersionedTransaction.deserialize(浏览器)或wallet.sendTransaction(Node)。connection.sendRawTransaction - →
lastValidBlockHeight,与反序列化后的交易中的connection.confirmTransaction配合使用。切勿调用新的tx.message.recentBlockhash(参见注意事项)。getLatestBlockhash - /
inAmount/outAmount/otherAmountThreshold/priceImpactPct→ 用于展示。slippageBps - /
prioritizationFeeLamports→ 回显/日志记录。服务器在解析prioritizationType后确定的优先费用选项。"auto" - → 日志记录/时效性检查。
contextSlot - → 可选展示/调试。
routePlan
OpenAPI中标记为*“仅当请求包含用户公钥时才返回”*的字段(、、、、)在仅报价的请求中会缺失——使用前请检查。
transactionlastValidBlockHeightcomputeUnitLimitprioritizationFeeLamportsaddressLookupTables完整可运行示例(服务器端版本):(链接至DFlow Cookbook仓库)。字段级 schema 详情请查看文档MCP。
Keypair/build/recipes/trading/imperative-tradeTrade — declarative /intent
+ /submit-intent
(opt-in)
/intent/submit-intent交易——声明式/intent
+ /submit-intent
(可选)
/intent/submit-intentUser signs an intent (asset pair, slippage, min-out); DFlow picks the route at execution time and fills via Jito bundles. Sells on: less slippage, better pricing, sandwich protection.
Hard restriction: does not support Token-2022 mints. Verify both mints are SPL before suggesting; otherwise stay on .
/intent/orderOnly suggest declarative when the user explicitly asks for sandwich protection or "best execution." Recipe details (intent shape, polling) via the docs MCP.
用户签署一个意向(资产对、滑点、最小输出);DFlow在执行时选择路由并通过Jito bundles完成交易。优势:更低滑点、更优定价、防三明治攻击。
硬性限制:不支持Token-2022代币铸造地址。建议前请验证两个代币均为SPL标准;否则请使用。
/intent/order仅当用户明确要求防三明治攻击或“最优执行”时,才建议使用声明式交易。意向结构、轮询等详情请查看文档MCP。
What to ASK the user (and what NOT to ask)
需要询问用户的内容(及无需询问的内容)
Trade shape — infer if unambiguous, confirm if not:
- Input + output token — base58 mint addresses. The CLI resolves a small symbol set (SOL, USDC, USDT, JUP, BONK, etc.); the API has no symbol resolver — base58 mints only.
- Amount in atomic units of the input token — = $0.50 USDC,
500_000= 1 SOL. Convert before calling.1_000_000_000
Infra — always ask, never infer:
- API only — wallet pubkey (base58). Required for every call.
/order - API only — DFlow API key (only when the script is making direct HTTP calls to or
/order; pure CLI scripts don't need one — see the "two auth paths" gotcha). Ask with a clean, neutral question: "Do you have a DFlow API key?" Don't presuppose where the key lives — phrasings like "do you have it in env?" or "is/quoteset?" nudge the user toward env-var defaults they didn't ask for. Surface the choice; don't silently fall back to env or to dev. It's one key for everything DFlow — sameDFLOW_API_KEYunlocks the Trade API and the Metadata API, REST and WebSocket. If yes → prod hostx-api-keywithhttps://quote-api.dflow.neton every request. If no → dev hostx-api-key(same features, rate-limited). Point them athttps://dev-quote-api.dflow.netfor a prod key. When you generate a script that does its own HTTP, log the resolved host + key-presence at startup so the user can see which rails they're on.https://pond.dflow.net/build/api-key - Priority fee (both surfaces) — "Any priority-fee preference, or just use DFlow's default?" Default on both surfaces = DFlow-auto, capped at 0.005 SOL (documented default on ). Surface this explicitly so the user knows the lever exists for congestion / cost-sensitive trades. Don't editorialize about what percentage of trades this covers — DFlow doesn't publish one and you don't know.
/order- API — pass on
prioritizationFeeLamports:/order|auto|medium|high|veryHigh| integer lamports. Ondisabled(declarative), roll the priority fee into/intent(the 10,000-lamport base processing fee). Live estimates for tuning:feeBudget = priority + 10_000(snapshot),GET /priority-fees(WebSocket)./priority-fees/stream - CLI — no tuning flag; always uses the server-side default. If the user needs finer control (an exact lamport value, or
dflow trade), they'll have to drop to the API.disabled
- API — pass
- Sponsored / gasless (API only — skip for CLI) — "Does the user need to hold SOL for this trade, or is your app covering fees?" Default = user pays. To sponsor, pass on
sponsor=<sponsor-wallet-base58>and co-sign the returned transaction with the sponsor keypair (both user and sponsor sign). Optional/orderpicks sponsor-executes (default) vs. user-executes. The CLI doesn't support sponsorship at all.sponsorExec=true|false
Do NOT ask about:
- RPC — CLI users set it during . Browser wallet-adapter apps using
dflow setupdon't need their own RPC for the broadcast — the wallet handles it (see the broadcast-path Gotcha). Only ask when signing server-side (Node +wallet.sendTransaction(tx, connection)), polling declarative trades, or when the app is explicitly going low-level withKeypairin the browser. When one is needed, suggest Helius.connection.sendRawTransaction - Slippage — both surfaces default to . Override only on explicit user request (
"auto"CLI;--slippageAPI).slippageBps - Platform fee, DEX inclusion/exclusion, route length, Jito bundles, direct-only routes — defaults are right for typical swaps; only surface these knobs on explicit user need. For platform fees specifically, defer to if the user pivots there.
dflow-platform-fees
交易形态——若明确则推断,若模糊则确认:
- 输入+输出代币——base58格式的铸造地址。CLI可解析少量符号(SOL、USDC、USDT、JUP、BONK等);API无符号解析功能——仅接受base58格式的铸造地址。
- 输入代币的原子单位数量——= 0.50美元USDC,
500_000= 1 SOL。调用前需转换。1_000_000_000
基础设施——务必询问,切勿推断:
- 仅API场景——钱包公钥(base58格式)。每次调用均需提供。
/order - 仅API场景——DFlow API密钥(仅当脚本直接调用或
/order的HTTP接口时需要;纯CLI脚本无需——参见“两种认证方式”注意事项)。请用清晰中立的问题询问:“你是否拥有DFlow API密钥?” 不要预设密钥的存储位置——诸如“你是否已将其存入环境变量?”或“/quote是否已设置?”的表述会引导用户使用他们未要求的环境变量默认值。提供选择;不要静默回退到环境变量或开发环境。一个密钥适用于所有DFlow服务——相同的DFLOW_API_KEY可解锁交易API和元数据API,REST和WebSocket均适用。若有→使用生产环境地址x-api-key,并在每个请求中携带https://quote-api.dflow.net。若无→使用开发环境地址x-api-key(功能相同,有速率限制)。可引导用户访问https://dev-quote-api.dflow.net获取生产环境密钥。当生成自行处理HTTP请求的脚本时,请在启动时记录解析后的地址+密钥状态,以便用户了解当前使用的环境。https://pond.dflow.net/build/api-key - 优先费用(两种操作方式均涉及)——“是否有优先费用偏好,还是使用DFlow的默认设置?”两种方式的默认值均为DFlow自动设置,上限为0.005 SOL(文档中记录的默认值)。需明确告知用户该选项存在,以便在网络拥堵或对成本敏感的交易中使用。不要主观判断该默认值适用于多少比例的交易——DFlow未公布相关数据,你也无法得知。
/order- API——在请求中传递
/order:prioritizationFeeLamports|auto|medium|high|veryHigh| 整数lamports。在声明式交易disabled中,将优先费用纳入/intent(10,000 lamport为基础处理费)。用于调整的实时估算:feeBudget = priority + 10_000(快照)、GET /priority-fees(WebSocket)。/priority-fees/stream - CLI——无调整标志;始终使用服务器端默认值。若用户需要更精细的控制(精确的lamport值或
dflow trade),则需使用API。disabled
- API——在
- 赞助式/无Gas费(仅API场景——CLI无需询问)——“用户是否需要持有SOL来支付此次交易费用,还是由你的应用承担费用?”默认值为用户支付。若要启用赞助,需在请求中传递
/order,并使用赞助方密钥对返回的交易进行共同签名(用户和赞助方均需签名)。可选参数sponsor=<sponsor-wallet-base58>选择赞助方执行(默认)还是用户执行。CLI完全不支持赞助功能。sponsorExec=true|false
无需询问的内容:
- RPC——CLI用户在时设置。使用
dflow setup的浏览器钱包适配器应用无需自行提供RPC进行广播——钱包会处理(参见广播方式注意事项)。仅在服务器端签名(Node +wallet.sendTransaction(tx, connection))、轮询声明式交易,或应用在浏览器中明确使用Keypair进行底层操作时才需要询问。若需要,推荐Helius。connection.sendRawTransaction - 滑点——两种方式均默认使用。仅在用户明确要求时才覆盖默认值(CLI使用
"auto";API使用--slippage)。slippageBps - 平台费用、DEX包含/排除、路由长度、Jito bundles、仅直接路由——默认设置适用于典型兑换;仅在用户明确需要时才展示这些选项。对于平台费用,若用户转向该话题,请参考技能。
dflow-platform-fees
Gotchas (the docs MCP won't volunteer these)
注意事项(文档MCP不会主动提及)
- Atomic units always. API rejects human-readable amounts. Confirm decimals each time — token metadata or RPC .
getParsedAccountInfo - API has no symbol resolver. The CLI has a small allow-list; the API only accepts base58 mints. Don't assume works on
"USDC"./order - Browser apps must proxy. Trading API serves no CORS — call it from a backend (Next.js API route or equivalent), never directly from the browser.
- Two broadcast paths in browser apps; pick the right one. In ,
@solana/wallet-adapter-reactdelegates to the wallet'swallet.sendTransaction(tx, connection)— Phantom and most major wallets route the broadcast through their own RPC, so the app'ssignAndSendTransactiononly needs to work for reads (Connection). A publicconfirmTransactionendpoint is fine for that. The low-level two-step (mainnet-beta+signTransaction(tx)) sends through the app's RPC — and public endpoints reliably 403 onconnection.sendRawTransaction(signed.serialize()). Default tosendTransactionin browser apps; drop to the two-step only when you need to inspect or modify the signed bytes before broadcast. Server-side signing (Node +wallet.sendTransaction) is always two-step, because there's no wallet adapter to delegate to — and there you do need a real RPC.Keypair - Wire wallets via Wallet Standard auto-discovery, not per-wallet adapters. Pass to
wallets={[]}. Modern Phantom / Solflare / Backpack / Glow / etc. implement the Wallet Standard protocol and are auto-detected at runtime — no explicit adapter instances needed. Do not instantiate<WalletProvider>/new PhantomWalletAdapter()fromnew SolflareWalletAdapter(); those are pre-Wallet-Standard shims, and the kicker is the@solana/wallet-adapter-walletsReact surface looks identical either way — sameuseWallet(), samesendTransaction. But underneath, the legacy adapter'spublicKeysilently downgrades tosendTransaction+signTransactionthrough your app's RPC, re-introducing the public-RPC 403 the previous gotcha just fixed. Empty-array auto-discovery also lets you drop theconnection.sendRawTransactiondep (and its@solana/wallet-adapter-wallets/@walletconnect/*tail).pino-pretty - Confirm against the blockhash DFlow signed with — never a fresh one. The blockhash is on the deserialized transaction: . Pair it with
tx.message.recentBlockhashfrom thelastValidBlockHeightresponse. Never call/orderfor confirmation. It's wrong two ways: (1) semantically — a freshly-fetched blockhash can be past theconnection.getLatestBlockhash()DFlow returned, solastValidBlockHeighttimes out on a transaction that actually landed; (2) operationally — publicconfirmTransactionnow 403smainnet-beta, andgetLatestBlockhashsurfaces that as@solana/web3.js, which falsely looks like you're using the deprecated"failed to get recent blockhash: ...". The right pattern is in the code sketch under thegetRecentBlockhashworkflow above./order - Declarative ≠ Token-2022. rejects Token-2022 mints. Stay on
/intentfor those (which is the default for everyone anyway)./order - is often a units or mint mistake before it's a liquidity issue. Before assuming no route exists, double-check you're passing atomic units (not human-readable amounts) and the mint addresses are correct.
route_not_found - is real. Trade size exceeds available liquidity; reduce
price_impact_too_high, or passamountonly with the user's explicit consent.priceImpactTolerancePct - Onchain failure with slippage logs. Don't silently bump on retry — surface to the user.
slippageBps - CLI shell-outs authenticate themselves; direct HTTP calls don't. If your script or backend shells out to , that leg uses the CLI's stored config from
dflow trade(key, wallet, RPC) — you plumb nothing for CLI invocations. If the same script also hits the Trade API or Metadata API directly over HTTP (e.g. scanner-style discovery, your owndflow setupcall,/order), that HTTP client needs the key handed in explicitly (env var,/quote,.envflag, header). The CLI's stored key is not reusable by a sibling HTTP client, and an env-var key is not injected into the CLI either — they're independent plumbing sites for the same DFlow key. Only ask about an API key for the HTTP portion; pure CLI scripts don't need one.--api-key
- 始终使用原子单位。API会拒绝人类可读的金额。每次需确认小数位数——可通过代币元数据或RPC的查询。
getParsedAccountInfo - API无符号解析功能。CLI有一个小的允许列表;API仅接受base58格式的铸造地址。不要假设可在
"USDC"中使用。/order - 浏览器应用必须使用代理。Trading API不支持CORS——请从后端(如Next.js API路由)调用,切勿直接从浏览器调用。
- 浏览器应用有两种广播方式;请选择正确的方式。在中,
@solana/wallet-adapter-react会委托给钱包的wallet.sendTransaction(tx, connection)——Phantom及大多数主流钱包会通过自身RPC进行广播,因此应用的signAndSendTransaction仅需处理读操作(Connection)。公共confirmTransaction端点足以满足该需求。底层两步法(mainnet-beta+signTransaction(tx))会通过应用的RPC发送——而公共端点在connection.sendRawTransaction(signed.serialize())时会可靠地返回403错误。浏览器应用默认使用sendTransaction;仅当需要在广播前检查或修改签名字节时才使用两步法。服务器端签名(Node +wallet.sendTransaction)始终使用两步法,因为没有钱包适配器可委托——此时你需要一个真实的RPC。Keypair - 通过Wallet Standard自动发现钱包,而非逐个钱包适配器。向传递
<WalletProvider>。现代Phantom / Solflare / Backpack / Glow等钱包均实现了Wallet Standard协议,会在运行时自动被检测到——无需显式实例化适配器。请勿从wallets={[]}实例化@solana/wallet-adapter-wallets/new PhantomWalletAdapter();这些是Wallet Standard出现前的兼容层,而new SolflareWalletAdapter()React接口在两种情况下看起来完全相同——相同的useWallet(),相同的sendTransaction。但在底层,旧版适配器的publicKey会静默降级为sendTransaction+signTransaction,通过你的应用RPC发送,这会重新引入之前注意事项中提到的公共RPC 403问题。空数组自动发现还可让你移除connection.sendRawTransaction依赖(及其@solana/wallet-adapter-wallets/@walletconnect/*依赖)。pino-pretty - 根据DFlow签名使用的区块哈希进行确认——切勿使用新获取的区块哈希。区块哈希位于反序列化后的交易中:。与
tx.message.recentBlockhash响应中的/order配合使用。切勿调用lastValidBlockHeight进行确认。这有两处错误:(1) 语义上——新获取的区块哈希可能超出DFlow返回的connection.getLatestBlockhash(),导致lastValidBlockHeight在交易实际已完成时超时;(2) 操作上——公共confirmTransaction端点现在会对mainnet-beta返回403,getLatestBlockhash会将其显示为@solana/web3.js,这会让人误以为你使用了已弃用的"failed to get recent blockhash: ..."。正确的模式已在上述getRecentBlockhash流程的代码示例中给出。/order - 声明式交易≠Token-2022。会拒绝Token-2022代币铸造地址。此类代币请使用
/intent(这也是默认方式)。/order - 通常是单位或铸造地址错误,而非流动性问题。在假设没有可用路由前,请再次检查是否传递了原子单位(而非人类可读金额)以及铸造地址是否正确。
route_not_found - 是真实存在的。交易规模超出可用流动性;请减少
price_impact_too_high,或仅在用户明确同意时传递amount。priceImpactTolerancePct - 链上失败且包含滑点日志。重试时请勿静默提高——需告知用户。
slippageBps - CLI调用会自行认证;直接HTTP调用不会。若你的脚本或后端调用,该部分会使用
dflow trade存储的CLI配置(密钥、钱包、RPC)——你无需传递任何参数给CLI调用。若同一脚本还通过HTTP直接调用交易API或元数据API(如扫描式发现、自行调用dflow setup、/order),则该HTTP客户端需要显式传入密钥(环境变量、/quote、.env标志、请求头)。CLI存储的密钥无法被同级HTTP客户端复用,环境变量中的密钥也不会注入到CLI中——它们是同一DFlow密钥的独立配置位置。仅在HTTP部分需要询问API密钥;纯CLI脚本无需。--api-key
When something doesn't fit
超出范围的内容
For anything not covered above — full parameter lists, full error tables, declarative intent shape, legacy + flow, sponsorship fields, new features — query the docs MCP (, ). Don't guess.
/quote/swapsearch_d_flowquery_docs_filesystem_d_flowFor runnable code, point the user at the DFlow docs recipes (each links to the DFlow Cookbook Repo for clone-and-go): , .
/build/recipes/trading/imperative-trade/build/recipes/trading/declarative-trade对于上述未涵盖的内容——完整参数列表、完整错误表、声明式意向结构、旧版 + 流程、赞助字段、新功能——请查询文档MCP(、)。请勿猜测。
/quote/swapsearch_d_flowquery_docs_filesystem_d_flow如需可运行代码,请引导用户查看DFlow文档教程(每个教程均链接至DFlow Cookbook仓库,可直接克隆使用):、。
/build/recipes/trading/imperative-trade/build/recipes/trading/declarative-tradeSibling skills
关联技能
Defer if the user pivots to:
- — Kalshi prediction-market YES/NO trades
dflow-kalshi-trading - — charge a builder cut on swaps
dflow-platform-fees
若用户转向以下话题,请转至对应技能:
- ——Kalshi预测市场的YES/NO交易
dflow-kalshi-trading - ——在兑换中收取开发者分成
dflow-platform-fees