Releases: TonCast/tx-sdk
Releases · TonCast/tx-sdk
v0.1.4
[0.1.4]
Fixed
- Self-referral is now allowed. The
REFERRAL_EQUALS_BENEFICIARYvalidation
that rejected bets wherereferral === beneficiaryhas 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).BetErrorCodeno longer includes"REFERRAL_EQUALS_BENEFICIARY".validateBetParamsno longer throws whenreferralequalsbeneficiary.
v0.1.3
[0.1.3]
Fixed
- Cross-hop swaps no longer compound slippage per leg. The user-set
slippageis 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 twogrossUpForSlippage
ceil ops).
- Before: a 5 % slippage on a 2-hop route (e.g.
PricedCoin.tonEquivalentfor cross-hop sources now reflects the
TRUE route-total worst-case delivery (expected × (1 − slippage)),
not the per-leg floor STON.fi returns onleg2.minAskUnits. UI
sliders bound bytonEquivalentthus 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.recommendedSlippagefor 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 againstuserSlippage.PricedCoin.recommendedMinAskUnitsfor cross-hop is recomputed
locally from the route-total recommendation
(tonEquivalentExpected × (1 − recommendedSlippage)), not taken
from the simulator's per-legrecommendedMinAskUnits(which would
be sized for the wrong slippage scale).simulateReverseCrossToTon(src/rates.ts) anddiscoverRoute'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.tsupdated to make the route-total
semantics explicit onrecommendedSlippage/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-endquote → confirmQuotesmoke
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 sametonEquivalent,
offerUnits, andminAskAmountas 0.1.2. - TON-funded paths are unaffected.
- This is a behavioural breaking change for UI consumers reading
tonEquivalentfor cross-hop sources — the value will be ~5 %
smaller for the same balance and slippage than in 0.1.2. UI
sliders bound bytonEquivalentwill 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. Seeexamples/bet-on-behalf.tsfor a worked
example.
v0.1.2
[0.1.2]
Changed
PricedCoin.tonEquivalentandPricedCoin.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
tonEquivalentdirectly without a per-source branch — matches the
way jetton sources have always worked (minAskUnitsfrom STON.fi). - Eliminates the failure mode introduced in 0.1.1 where UI passed
coin.amountasmaxBudgetTon, the strategy filled it almost
entirely, planner emitted aninsufficient_balancewarning under
allowInsufficientBalance: true, and the wallet refused to sign
whenvalue + send-fee > balance. With the new semantics, sliders
bound bytonEquivalent(or bymaxBudgetTon = tonEquivalent)
leavewalletReserveuntouched on the wallet automatically. - The raw on-wallet balance remains available as
coin.amount.
- Field meaning is now uniform across TON and jetton: "how much
availableForBet(coin, walletReserve)semantics unchanged — for TON
it still recomputes fromcoin.amount, so it can be called with a
differentwalletReservethanpriceCoinswas given. When the same
reserve is used, it returns exactlycoin.tonEquivalent.- Documentation in
pricing.ts,types.tsupdated; test fixtures
(priceTon/tonPricedhelpers) and assertions adjusted.
Notes
- Jetton-source pricing is unchanged.
availableForBetandBetOption.breakdown.spendare unaffected (they
already returned the correct numbers); this release just makes
tonEquivalentitself the single source of truth for UI sizing.- Combined with 0.1.1's
TON_DIRECT_GAS = 0n, the recommended UI flow
now is:slider.max = coin.tonEquivalent,quoteXxxBet({ maxBudgetTon: coin.tonEquivalent })(Market mode)
or any value≤ coin.tonEquivalent(Fixed / Limit),quote.option.breakdown.spendmatches what the wallet shows as
"Sent" pixel-for-pixel.
v0.1.1
[0.1.1]
Changed
TON_DIRECT_GASdefault is now0n(was50_000_000n/ 0.05 TON).
PARI_EXECUTION_FEE(0.1 TON × N entries, already insidetotalCost)
fully covers Pari's forward fees, storage, and compute gas; no extra
surplus needs to be attached to the messagevalue. Practical effect:- For TON-funded bets, the wallet's "Sent" amount now matches the UI's
"Total" line exactly (wastotalCost + 0.05 TON, surplus refunded
later via a separate tx). PricedCoin.gasReservefor TON sources is now0n.availableForBet(tonCoin, walletReserve)now returns
balance − walletReserve(wasbalance − 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.
- For TON-funded bets, the wallet's "Sent" amount now matches the UI's
- 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.tsupdated to reflect the new default.
Notes
- Jetton-funded paths are unaffected (
TON_DIRECT_GASis referenced only
in TON-direct code paths).DEX_CUSTOM_PAYLOAD_FORWARD_GAS(0.1 TON
for the proxy hop) and the*_HOP_JETTON_GAS_ESTIMATEreserves remain
unchanged. - Test fixtures updated:
tonPriced(amount)/priceTon(amount)
helpers now usegasReserve: 0nandviable: amount > walletReserve.