Skip to content

Releases: TonCast/tx-sdk

v0.1.4

29 Apr 14:58

Choose a tag to compare

[0.1.4]

Fixed

  • Self-referral is now allowed. The REFERRAL_EQUALS_BENEFICIARY validation
    that rejected bets where referral === beneficiary has been removed — there is
    no contract-level restriction on self-referral, so the SDK check was
    over-restricting valid use-cases (e.g. a bettor routing their own referral
    share back to themselves).
    • BetErrorCode no longer includes "REFERRAL_EQUALS_BENEFICIARY".
    • validateBetParams no longer throws when referral equals beneficiary.

v0.1.3

27 Apr 11:24

Choose a tag to compare

[0.1.3]

Fixed

  • Cross-hop swaps no longer compound slippage per leg. The user-set
    slippage is now treated as a route-TOTAL budget (matching STON.fi /
    Omniston UI semantics), and the SDK splits it into a tighter per-leg
    slippage internally — perLeg = 1 − √(1 − slippage) — so the composed
    worst-case across both legs equals the user's stated slippage.
    • Before: a 5 % slippage on a 2-hop route (e.g. TCAST → USDT → TON) was applied as 5 % per leg, grossing the offer jetton up by
      1/(1 − 0.05)² ≈ 1.108×. Users observed wallets requesting ~5 %
      more jetton than the planner's linear estimate showed (mainnet:
      UI quoted 26.8 TCAST; wallet asked for 28.21 TCAST for the same
      bet).
    • After: total gross-up across the route is 1/(1 − slippage) ≈ 1.053×, exactly the same factor as a direct swap at the same
      slippage. The wallet's "Sent" amount now matches the planner's
      linear estimate within ±2 % (rounding from two grossUpForSlippage
      ceil ops).
  • PricedCoin.tonEquivalent for cross-hop sources now reflects the
    TRUE route-total worst-case delivery
    (expected × (1 − slippage)),
    not the per-leg floor STON.fi returns on leg2.minAskUnits. UI
    sliders bound by tonEquivalent thus expose ~5 % less max-bet
    capacity than 0.1.2 — but every TON inside the new range is now
    guaranteed to confirm without the wallet asking for unexpectedly
    more jetton.

Changed

  • New helpers in src/utils/slippage.ts:
    • perLegSlippage(total, legCount) — splits a route-total budget
      into per-leg (legCount=1 is a no-op for direct routes).
    • combineLegSlippage(perLeg, legCount) — inverse: composes per-leg
      recommendations into route-total for like-for-like comparison
      against the user's slippage.
  • PricedCoin.recommendedSlippage for cross-hop is now the route-total
    composition of both per-pool recommendations
    (1 − (1 − r1)(1 − r2)), not the larger of the two leg values. It
    can be compared directly against userSlippage.
  • PricedCoin.recommendedMinAskUnits for cross-hop is recomputed
    locally from the route-total recommendation
    (tonEquivalentExpected × (1 − recommendedSlippage)), not taken
    from the simulator's per-leg recommendedMinAskUnits (which would
    be sized for the wrong slippage scale).
  • simulateReverseCrossToTon (src/rates.ts) and discoverRoute's
    cross-hop simulator calls (src/routing/discover.ts) now pass
    perLegSlippage(slippage, 2) to STON.fi instead of the user's
    route-total slippage. Direct routes are unchanged.
  • Field-level JSDoc in src/types.ts updated to make the route-total
    semantics explicit on recommendedSlippage / effectiveSlippage.

Added

  • New regression tests:
    • tests/utils/slippage.test.ts — round-trip and edge cases for
      perLegSlippage / combineLegSlippage.
    • tests/pricing.test.ts — pins the linear-estimate ↔ confirm-offer
      ratio at ≈ 1.0 for cross-hop (was ≈ 1.05 under the old code).
    • tests/sdk.test.ts — end-to-end quote → confirmQuote smoke
      tests for cross-hop with all three modes (fixed, limit,
      market), plus a "max-capacity bet still confirms" guard.

Notes

  • Direct (1-hop) routes are mathematically unchanged: perLegSlippage(s, 1)
    is the identity, so direct paths emit the same tonEquivalent,
    offerUnits, and minAskAmount as 0.1.2.
  • TON-funded paths are unaffected.
  • This is a behavioural breaking change for UI consumers reading
    tonEquivalent for cross-hop sources — the value will be ~5 %
    smaller for the same balance and slippage than in 0.1.2. UI
    sliders bound by tonEquivalent will automatically respect the
    new ceiling and stop offering bets that the wallet would have
    silently re-priced upward.
  • Mainnet smoke-test on the cross-hop path is recommended before any
    production deploy. See examples/bet-on-behalf.ts for a worked
    example.

v0.1.2

23 Apr 12:24

Choose a tag to compare

[0.1.2]

Changed

  • PricedCoin.tonEquivalent and PricedCoin.tonEquivalentExpected
    for TON sources now collapse to the spendable amount
    (=
    amount − walletReserve − gasReserve), instead of the raw on-wallet
    balance.
    • Field meaning is now uniform across TON and jetton: "how much
      TON can this coin contribute to a bet". UI sliders read
      tonEquivalent directly without a per-source branch — matches the
      way jetton sources have always worked (minAskUnits from STON.fi).
    • Eliminates the failure mode introduced in 0.1.1 where UI passed
      coin.amount as maxBudgetTon, the strategy filled it almost
      entirely, planner emitted an insufficient_balance warning under
      allowInsufficientBalance: true, and the wallet refused to sign
      when value + send-fee > balance. With the new semantics, sliders
      bound by tonEquivalent (or by maxBudgetTon = tonEquivalent)
      leave walletReserve untouched on the wallet automatically.
    • The raw on-wallet balance remains available as coin.amount.
  • availableForBet(coin, walletReserve) semantics unchanged — for TON
    it still recomputes from coin.amount, so it can be called with a
    different walletReserve than priceCoins was given. When the same
    reserve is used, it returns exactly coin.tonEquivalent.
  • Documentation in pricing.ts, types.ts updated; test fixtures
    (priceTon / tonPriced helpers) and assertions adjusted.

Notes

  • Jetton-source pricing is unchanged.
  • availableForBet and BetOption.breakdown.spend are unaffected (they
    already returned the correct numbers); this release just makes
    tonEquivalent itself the single source of truth for UI sizing.
  • Combined with 0.1.1's TON_DIRECT_GAS = 0n, the recommended UI flow
    now is:
    1. slider.max = coin.tonEquivalent,
    2. quoteXxxBet({ maxBudgetTon: coin.tonEquivalent }) (Market mode)
      or any value ≤ coin.tonEquivalent (Fixed / Limit),
    3. quote.option.breakdown.spend matches what the wallet shows as
      "Sent" pixel-for-pixel.

v0.1.1

23 Apr 12:05

Choose a tag to compare

[0.1.1]

Changed

  • TON_DIRECT_GAS default is now 0n (was 50_000_000n / 0.05 TON).
    PARI_EXECUTION_FEE (0.1 TON × N entries, already inside totalCost)
    fully covers Pari's forward fees, storage, and compute gas; no extra
    surplus needs to be attached to the message value. Practical effect:
    • For TON-funded bets, the wallet's "Sent" amount now matches the UI's
      "Total" line exactly (was totalCost + 0.05 TON, surplus refunded
      later via a separate tx).
    • PricedCoin.gasReserve for TON sources is now 0n.
    • availableForBet(tonCoin, walletReserve) now returns
      balance − walletReserve (was balance − walletReserve − 0.05 TON),
      so UI sliders sized via this helper can use up to ~0.05 TON more
      of the user's balance for the same wallet reserve.
  • Override per-call still available via BuildTonBetTxParams.tonDirectGas
    for callers who have a verified mainnet reason to attach a surplus.
  • Documentation in constants.ts, builders/ton.ts, pricing.ts, and
    types.ts updated to reflect the new default.

Notes

  • Jetton-funded paths are unaffected (TON_DIRECT_GAS is referenced only
    in TON-direct code paths). DEX_CUSTOM_PAYLOAD_FORWARD_GAS (0.1 TON
    for the proxy hop) and the *_HOP_JETTON_GAS_ESTIMATE reserves remain
    unchanged.
  • Test fixtures updated: tonPriced(amount) / priceTon(amount)
    helpers now use gasReserve: 0n and viable: amount > walletReserve.