Skip to content

feat(wallets): add TON Connect wallet option (Chain.Ton + Jettons) - #108

Merged
towanTG merged 6 commits into
swapkit:developfrom
GiMa-SwapKit:feat/tonconnect-wallet
Jul 30, 2026
Merged

feat(wallets): add TON Connect wallet option (Chain.Ton + Jettons)#108
towanTG merged 6 commits into
swapkit:developfrom
GiMa-SwapKit:feat/tonconnect-wallet

Conversation

@GiMa-SwapKit

Copy link
Copy Markdown
Contributor

Summary

Adds TON Connect as a wallet option, exported as @swapkit/wallets/tonconnect. TON Connect is the standard wallet connection protocol for the TON blockchain and supports only Chain.Ton, including the native token and Jettons.

Implementation

  • Follows the Xaman pattern (single-chain, remote-signing protocol): createWallet wrapper in packages/wallets/src/tonconnect/ with supportedChains: [Chain.Ton] and directSigningSupport: { [Chain.Ton]: true }.
  • Wraps @tonconnect/ui v3 for the connect modal, universal links, and bridge sessions. Connection uses openModal + onStatusChange (the connectWallet helper is deprecated in v3), detects user cancellation via the modal's action-cancelled close reason, and supports session restore via connectionRestored. An existing TonConnectUI instance can be injected for apps already using @tonconnect/ui-react; otherwise one is created from manifestUrl.
  • Delegates message building (native TON and Jetton transfers), balances, and fee estimation to the signerless @swapkit/toolboxes/ton toolbox via createTransaction({ sender }). Signing and broadcasting are routed through the connected wallet's sendTransaction; the returned hash is the external-message cell hash, identical to what toolbox.broadcastTransaction returns.
  • Mainnet is enforced via setConnectionNetwork(CHAIN.MAINNET) plus a post-connect check that disconnects testnet wallets.
  • Registered in loadWallet, SKWallets, and the supported-chains map; ./tonconnect subpath export added (the builder picks entrypoints up from package.json exports automatically). Changeset included.

Protocol constraints

  • Message addresses are normalized to TEP-2 user-friendly form (wallets reject raw 0:<hex>); the connected account's raw address is converted to non-bounceable UQ….
  • TON Connect messages carry no sendMode (the wallet chooses it), so sweep transactions (CARRY_ALL_REMAINING_BALANCE) are rejected with a clear error.
  • Detached signing (sign) is not part of the protocol and throws; use signAndBroadcastTransaction / transfer.

⚠️ Depends on swapkit/sdk release

CI will show 5 type errors until the SDK side ships — this is expected:

  1. @swapkit/helpers: one-line addition to the WalletOption enum: TON_CONNECT = "TON_CONNECT",
  2. @swapkit/toolboxes: a release exposing the ./ton subpath (the recently added TON toolbox)

Once released, both versions get bumped in packages/wallets/package.json and CI goes green. Verified locally against patched copies simulating that state: bun tsc --noEmit clean, biome clean, package builds with the new entry.

Usage

connectTonConnect([Chain.Ton], {
  manifestUrl: "https://yourapp.com/tonconnect-manifest.json",
});

towanTG and others added 4 commits July 30, 2026 12:46
…tion/SwapKitError registries)

Family-consistent pin via root override + all manifests; lockfile
regenerated with bun 1.3.13. Carrier for sdk#346 until helpers stable
ships; needed by the TON Connect wallet (swapkit#108).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sible registry

helpers rc converts WalletOption from enum to const+union; enum-member
type positions (TS2702) become typeof member lookups. Literal-type
rewrites only, no runtime change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… guard on array shape, registry adoption, honest fee estimate

- adopt the extensible WalletOption registry: module augmentation +
  registerWalletOption in tonconnect/register.ts, imported eagerly from
  utils.ts (the loadWallet match reads the value before the lazy import)
- destinations: raw-form addresses now convert to the BOUNCEABLE friendly
  form via @ton/core, matching the TON toolbox convention (failed contract
  sends refund); @tonconnect/sdk's toUserFriendlyAddress only emits the
  non-bounceable form and silently flipped the flag
- sweep guard now also reads messages[0].sendMode on the legacy bare-array
  transaction shape (was bypassable)
- estimateTransactionFee mirrors the toolbox's real transfer budget instead
  of inheriting its silent flat-0.01 signerless fallback (jettons ~0.06)
- injected TonConnectUI instances are remembered by the shared-instance
  cache; config-less follow-up calls no longer demand a manifestUrl
- unit tests for registration, destination normalization, and sweep guard

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@towanTG
towanTG force-pushed the feat/tonconnect-wallet branch from 9e3d60e to aed097b Compare July 30, 2026 09:31
towanTG and others added 2 commits July 30, 2026 13:33
…hangeset

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ule init requires localStorage

Eager value imports crashed non-DOM runtimes (bun test on CI, SSR/node).
CHAIN.MAINNET is inlined as the protocol constant; the account address is
derived via @ton/core instead of toUserFriendlyAddress.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
towanTG added a commit that referenced this pull request Jul 30, 2026
#134)

* chore: pin @swapkit/helpers to rc-20260728115044 (extensible WalletOption/SwapKitError registries)

Family-consistent pin via root override + all manifests; lockfile
regenerated with bun 1.3.13. Carrier for sdk#346 until helpers stable
ships; needed by the TON Connect wallet (#108).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: rewrite WalletOption member types to typeof-form for the extensible registry

helpers rc converts WalletOption from enum to const+union; enum-member
type positions (TS2702) become typeof member lookups. Literal-type
rewrites only, no runtime change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: stabilize lockfile to bun 1.3.13 fixed point + generated dep changeset

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@towanTG
towanTG merged commit 61a7689 into swapkit:develop Jul 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants