摘要本文介绍了我们建议 Skip Go API 集成方实现的若干 UI/UX 原则,以防止用户因以糟糕的执行价格进行兑换而伤害自己。我们将这些原则统称为 S.A.F.E.本文介绍了 S.A.F.E 框架,并提供了详细指引,说明你如何利用 Skip Go API 提供的信息来实现这一框架,并为用户带来无忧的兑换体验。
让你的应用保障用户安全
许多用户并不了解跨链兑换和转账背后的技术。因此,他们会采取一些不符合自身利益的操作:- 在并不理解的情况下,以不利价格执行兑换和转账,并使用自己无法承受损失的资金(例如:某个新发行、流动性很差的 meme 币上线 2 小时内就投入 1000 美元)
- 将他们的损失归咎于你(以及 Skip),即使你的软件和我们的软件都按预期运行;他们会要求退款,如果你不退款,还可能公开抹黑和骚扰你。
- Share:共享所有可用的预期执行价格信息
- Alert:当信息表明某个操作可能有害时发出提醒
- Fail:对触发提醒的交易直接失败处理(即那些看起来很可能伤害用户的交易)
- Enforce:对仍然想创建此类交易的用户强制增加额外审批步骤
S. 分享信息
你应该尽可能向用户展示有关预估兑换的全部信息。幸运的是,/fungible/route 和 /fungible/msgs_direct 接口会返回大量有用信息。
除了展示预估输入和输出数量(这些是最基础的),我们还建议展示:
- 输入金额的预估美元价值(
response.usd_amount_in) - 输出金额的预估美元价值(
response.usd_amount_out) - 价格影响(
response.swap_price_impact_percent)— 该指标衡量用户预期执行价格与执行时链上现货价格之间的偏差程度。价格影响高,意味着用户的兑换规模相对于其所对接的链上可用流动性过大,因此极有可能成交在一个糟糕的价格。 - 兑换场所(位于
response.operations中swap操作的swap_venue字段)- 这会告诉用户底层兑换实际发生在哪个 DEX 上,有助于避免用户对价格产生困惑。如果 API 返回了异常路径,将用户路由到他们不熟悉、不想使用的 DEX,或者路由到目标代币流动性较差的 DEX,这个信息会非常有用(例如在本文撰写时,Osmosis 上的 SEI 流动性比较稀薄) - 跨桥手续费金额(位于
response.operations中transfer和axelar_transfer条目下的fee_asset与fee_amount)— 这些表示路径中各桥从用户处收取的手续费,以及手续费对应的代币种类。展示这一点很重要,因为有时桥会收取用户意料之外的费用(例如 Noble 曾经对 IBC 转账收取 0.10% 手续费),而且有时费用会非常高(例如在 gas 价格较高的时期,Axelar 手续费可能高达 200 美元) - 跨桥手续费金额的美元价值(位于
response.operations中transfer和axelar_transfer条目下的usd_fee_amount)— 这能让用户理解这些手续费的实际成本。在更复杂的兑换和转账场景中,手续费是在路径中的中间环节收取的,用户可能很难直观理解这些底层手续费代币的含义。
/route 并向用户展示报价之后,只有调用 /msgs 才能生成正确的消息。(调用 /route 之后不要再调用 /msgs_direct,因为这会重新生成报价)
另一种方式是直接调用 /msgs_direct,只用 1 次请求同时生成报价信息和待签名交易。请记住,这些接口并不是确定性的,再次调用任一接口都会生成不同结果,用户执行的就不再是他们以为自己正在执行的交易。
A. 针对糟糕价格提醒用户
我们建议至少在以下三种场景中提醒用户:- 高价格影响(
swap_price_impact > PRICE_IMPACT_THRESHOLD): 这表示用户的兑换执行价格明显差于链上现货价格,也就是说,他们实际拿到的价格可能比自己预期的更差。这也说明其交易规模相对于链上可用流动性较大。我们建议在计算中使用PRICE_IMPACT_THRESHOLD = 2.5 - 输入与输出相对美元价值差异过高(
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > USD_REL_VALUE_THRESHOLD): 这用于估算用户因为兑换而立即损失的底层价值,并以输入价值的百分比表示。这个数值越高,表示用户会立刻损失其初始代币价值中更大的一部分。例如,数值为 50 表示用户会损失其输入预估价值的 50%。我们建议使用USD_REL_VALUE_THRESHOLD=2.5 - 手续费过高(
usd_fee_amount / usd_amount_in > FEE_THRESHOLD): 这表示路径中桥收取的手续费价值,占被转移基础金额的比例过高。如果这个值很高,用户可能更适合等到需要跨桥更多资金时再执行(因为桥手续费通常不会随金额同比例增长)。我们建议将FEE_THRESHOLD=.25
- 将异常偏高或偏低的报价数字加粗,或以其他方式让它比周围文本和数字更醒目
- 自动展开原本默认收起的下拉区域或详情面板,以显示触发提醒的字段
- 用红色、黄色或其他明显表示危险的颜色高亮问题报价数字,并且/或者将其他数字置灰
PRICE_IMPACT_THRESHOLD 时,我们会自动展开通常用于隐藏价格影响的下拉区域,并将整个字段高亮为红色。

F. 当交易可能伤害用户时直接失败
我们建议对那些可能对用户造成显著伤害的交易直接进行拦截,即使用户看起来仍然想完成这笔交易。 我们建议在以下场景中让用户交易失败或被阻止:- 输入与输出相对美元价值差异超过 10%
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > 10 - 价格影响超过 10%(
swap_price_impact > 10)
E. 强制显式的额外审批
如果你不想对超出安全阈值的交易直接失败处理,一个可行的替代方案是在允许用户签名交易之前,要求其完成额外的审批步骤。 重要的是,这种做法不同于仅仅提醒用户报价中的某些部分看起来不利,它的干扰程度更高。这意味着你需要在用户和他们想执行的兑换之间增加额外点击步骤,并要求他们明确同意执行一笔你的 UI 已经表明价格不佳的兑换。 例如,这是 go.skip.build 的警告页面:
- 页面顶部的 “Bad Trade Warning” 非常明确地表达了我们的预期:这笔兑换会伤害用户
- 页面会明确提醒用户问题所在,突出显示预测的价格影响,并要求他们再次确认这一点
- “顺畅路径”或“默认路径”是返回,而不是完成兑换(注意 “Go Back” 按钮被高亮显示)
- 输入与输出相对美元价值差异超过 5%
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > 5 - 价格影响超过 5%(
swap_price_impact > 5) - 无法计算价格影响和相对美元价值差异(即缺少
swap_price_impact、usd_amount_out和/或usd_amount_in)
选择合适的保护级别:警告、额外审批与直接失败
这一权衡很重要,因为保护用户通常会直接与更简洁、更顺畅、更强大的用户体验形成冲突。例如,过多的警告可能会让那些明知自己在交易低流动性垃圾币的用户感到厌烦,而额外的审批步骤则可能让非常看重速度的专业交易者感到沮丧。 对于任何你可能用于判断交易是否会伤害用户的安全指标,都可以考虑实现 4 个安全层级。从最不安全、干扰最小,到最安全、干扰最大:- 无:直接放行。不给用户任何提示,也不做任何减速或阻止交易的事情。
- 提醒:使用某种视觉提示,告知用户这笔兑换可能需要谨慎对待
- 强制额外审批:要求用户额外点击后才能真正执行兑换,并将警告置于前景位置,让用户必须显式确认。
- 失败:对超出你安全容忍范围的交易,直接阻止、失败或拦截
- 对较弱的安全措施设置更低的触发阈值,对较强的安全措施设置更保守的阈值(例如:你可以在价格影响达到 2.5% 时提醒用户,在达到 10% 时要求额外审批,在达到 25% 时直接让交易失败。)这种方式的好处在于,它既能让特别保守的用户意识到自己可能面临一定风险,又不会过度妨碍他们;同时,对于那些大概率任何交易者都无法接受的严重失败情况,仍然能够强制拦截。
- 当较高金额交易超出安全容忍范围时,使用更强的安全措施(例如:当输入金额在 0 到 100 美元之间且价格影响大于 10% 时,你可以只给出警告;当输入金额在 1,000 到 10,000 美元之间时,要求额外审批;而当金额超过 1 万美元且价格影响仍大于 10% 时,则直接阻止交易。)
有问题或反馈?帮助我们做得更好!加入我们的 Discord,并选择 “Skip Go Developer” 角色,与我们分享你的问题和反馈。
SummaryThis doc covers several UI/UX principles we recommend Skip Go API integrators implement to protect users from harming themselves by swapping at bad execution prices. Collectively, we refer to these principles as S.A.F.E.The document introduces the S.A.F.E framework and provides detailed guidance for how you can use the information provided in the Skip Go API to implement the framework & give your users a worry-free swapping experience.
Keeping Users Safe on your Application
Many users are unfamiliar with the technology behind cross-chain swaps and transfers. As a result they will take actions that aren’t in their best interests:- Execute swaps & transfers they don’t understand at unfavorable prices using money they cannot afford to lose (e.g. Spending $1000 on a new, illiquid meme coin within 2 hours of launch)
- Accuse you (& Skip) of responsibility for their losses (even if your software & ours worked as expected), demand a refund, and publicly vilify & troll you if you do not give one.
- Share all available information about expected execution price
- Alert when info indicates an action might be harmful
- Fail transactions that trigger your alerts (i.e. transactions that seem likely to harm users)
- Enforce additional approval stages for users who want to create these transactions anyhow
S.hare Info
You should share as much information about the estimated swap with your users as possible. Fortunately, the/fungible/route and /fungible/msgs_direct endpoints return a ton of useful information.
In addition to showing estimated amount in and out (the obvious ones), we recommend showing:
- Estimated USD value of the amount in (
response.usd_amount_in) - Estimated USD value of the amount out (
response.usd_amount_out) - Price Impact (
response.swap_price_impact_percent) — This measures how much the user’s expected execution price differs from the current on-chain spot price at time of execution. A high price impact means the user’s swap size is large relative to the available on chain liquidity that they’re swapping against, which makes a bad price very likely. - Swapping Venue (Available in the
swap_venuefield of theswapoperation inresponse.operations) - This tells the user what DEX they’re actually performing the underlying swap on, which helps avoid confusion about prices. This can be useful information in the event the API returns an usual route and routes the user to a DEX they’re unfamiliar with / don’t want to use or to a DEX where there’s not much liquidity of the token they’re swapping (e.g. SEI liquidity on Osmosis is sparse at the time of this writing) - Bridge Fee Amounts (Available in the
transferandaxelar_transferentries inresponse.operationsunderfee_assetandfee_amount) — These represent the fees that bridges take from the user along the route, denominated in the token(s) they’re taking. It’s important to show because sometimes bridges take fees unexpectedly (e.g. Noble used to take 0.10% fee on IBC transfers), and sometimes they take large fees (e.g. During periods of high gas prices, Axelar fees can be as high as $200) - USD value of bridge fee amounts (Available in the
transferandaxelar_transferentries inresponse.operationsunderusd_fee_amount) — This gives the user a sense of the actual cost of their fee amounts. In cases of more complex swaps and transfers, the user might have a hard time making sense of the underlying fee tokens because the fees are being charged at an intermediate point in the route
/route and displayed the quote to the user, a call to /msgs is the only way to generate the correct message. (DO NOT call /msgs_direct after calling /route since this will regenerate the quote)
Alternatively you can call /msgs_direct to both generate the quote information and the transaction that needs to be signed with 1 request. Remember that these endpoints are not deterministic and calling either again will generate a different output and your user will not execute the transaction they think they are executing.
A.lert users to bad prices
We recommend alerting users in the following three scenarios at least:- High Price Impact (
swap_price_impact > PRICE_IMPACT_THRESHOLD) : This indicates the user’s swap is executing at a considerably worse price than the on-chain spot price — meaning they’re probably getting a worse price than they think they should. It also indicates the size of their trade is large relative to the available on chain liquidity. We recommend usingPRICE_IMPACT_THRESHOLD = 2.5in your calculations - High difference in relative USD value in and out (
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > USD_REL_VALUE_THRESHOLD): This estimates the underlying value the user will lose instantly as a result of swapping, represented as a percentage of the value of their input. A high value for this figure indicates the user is instantly losing a large percentage of the value of their starting tokens. For example, a value of 50 indicates the user loses 50% of the estimated value of their input. We recommend usingUSD_REL_VALUE_THRESHOLD=2.5 - High fees (
usd_fee_amount / usd_amount_in > FEE_THRESHOLD) : This indicates that the value of fees charged by bridges used in the route amount to a large percentage of the underlying amount being transferred. If this value is high, user might want to wait until bridging more funds to execute (since bridge fees rarely scale with volume). We recommend settingFEE_THRESHOLD=.25
- Bolding unusually high/low quote numbers — or otherwise making them larger than surrounding text/numbers
- Automatically opening drop downs / detail panes that are usually closed by default to display the alert field
- Highlighting the offending quote number in red, yellow, or some other loud color indicating danger and/or greying out other numbers
PRICE_IMPACT_THRESHOLD on go.skip.build, we auto-open the drop-down that normally hides price impact and highlight the whole field in red.

F.ail Transactions when they’re likely to cause user harm
We recommend preventing transactions that may significantly harm the user altogether — even if your user seems to want to complete the transaction. We recommend failing/preventing user transactions in the following scenarios:- Greater than 10% difference in relative USD value in and out
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > 10 - Greater than 10% price impact (
swap_price_impact > 10)
E.nforce explicit, additional approval
If you do not want to fail transactions that exceed safety thresholds outright, one viable alternative is to require additional stages of user approval before letting the user sign the transaction. Importantly, this is different and more disruptive than simply warning the user about some aspect of the quote looking unfavorable. This means putting additional clicks between the user and the swap they want to perform, and having them explicitly agree to performing a swap your UI indicates will have a bad price. For example, this is go.skip.build’s warning screen:
- It’s very clear that our expectation is that the swap will harm the user with the “Bad Trade Warning” across the top
- The page explicitly reminds the user what the problem is — foregrounding the predicted price impact and forcing them to acknowledge it again
- The “happy path” or “default” path is to go back — not to finish the swap (Notice that the “Go Back” button is highlighted)
- Greater than 5% difference in relative USD value in and out
(usd_amount_in - usd_amount_out)/usd_amount_in)*100 > 5 - Greater than 5% price impact (
swap_price_impact > 5) - Price impact AND relative-USD-value-difference cannot be calculated (i.e.
swap_price_impact,usd_amount_out, and/orusd_amount_inare missing)
Choosing the right level of protection: warnings, additional approvals, and outright failures
It’s important to think about this tradeoff because protecting users often directly trades off against making a cleaner, simpler, and more powerful user experiences. For example, excessive warnings might get annoying to users who know they’re trading illiquid shitcoins, and additional steps of approval might frustrate pro traders who care deeply about speed For any safety metric you might track to determine whether a transaction could harm a user, consider 4 tiers of safety you can implement. From least safe and least disruptive to most safe and most disruptive:- None: Just let it rip. Don’t give the user any heads up. Don’t do anything to slow them down or prevent them from trading.
- Alert: Use some visual cue to indicate to the user that they should be wary about swap
- Enforce additional approval: Require additional clicks to actually execute the swap and foreground the warning — so the user needs to approve it explicitly.
- Fail: Just block / fail / prevent transactions that exceed your safety tolerance bounds outright
- Set lower trigger thresholds for weaker forms of security and more conservative thresholds for stronger forms of security (e.g. You could alert users about high price impact at 2.5%, require an additional stage of approval at 10%, and fail the transaction outright at 25%) This approach is nice because it gives users who may be very conservative some indication that they may face some danger without getting in their way too much, while still hard-stopping more inexcusable failures that are probably never acceptable to any trader
- Use stronger forms of security when safety tolerances are exceeded for higher value transactions (e.g. You could use warnings when price impact is greater than 10% for transactions where the amount in is 1,000 - 10,000, and block transactions above $10k outright if price impact is greater than 10%.
Have questions or feedback? Help us get better!Join our Discord and select the “Skip Go Developer” role to share your questions and feedback.