Set up a TypeScript project, connect the required STON.fi and TON components, and prepare a reliable foundation for swaps and liquidity operations.
Installing the STON.fi SDK requires more than adding one npm package. The SDK creates and opens the smart contract wrappers your application needs, but a complete integration usually also requires a TON RPC client, the STON.fi API, and a wallet connection layer.
For a production swap application, these components work together. The STON.fi API discovers assets, simulates the trade, and returns the correct Router metadata. The SDK converts that information into contract instances and transaction parameters. TON Connect then asks the user's wallet to approve and send the transaction.
The official SDK is written for JavaScript and TypeScript applications and acts as a thin wrapper around STON.fi contracts, including Router, Pool, LP Account, Vault, and pTON contracts.
Key takeaways
- Install
@ston-fi/sdktogether with@ston-fi/apiand@ton/ton. - Add a TON Connect package when users will sign transactions through a wallet.
- Use the STON.fi API to simulate operations and discover the appropriate Router.
- Avoid hardcoding mainnet Router addresses in production integrations.
- Keep blockchain units, RPC access, wallet signing, and API data as separate layers.
What the STON.fi SDK actually provides
The SDK is the contract interaction layer of a STON.fi integration. It gives your application TypeScript classes and helper functions for working with STON.fi smart contracts without manually constructing cells, operation codes, and message bodies.
Its main responsibilities include:
- creating Router and Pool contract wrappers
- preparing swap transaction parameters
- preparing liquidity deposit and withdrawal parameters
- opening LP Account and Vault contracts
- representing pTON when the native TON asset is involved
- converting API Router metadata into the correct contract classes
The current v2 documentation covers newer contract functionality such as single-sided liquidity provision, Vault operations, additional pool types, and improved gas handling. The repository still includes v1 classes because existing pools and integrations may continue to use them.
The SDK does not replace every other component in your application. It does not provide a token search interface, store private keys, choose a wallet for the user, or guarantee that a proposed transaction is economically suitable.
A useful mental model is:
| Component | Main responsibility |
|---|---|
@ston-fi/api |
Assets, pools, Router metadata, simulations, and protocol data |
@ston-fi/sdk |
Smart contract wrappers and transaction parameters |
@ton/ton or the SDK Client
|
Reading TON blockchain state through an RPC endpoint |
| TON Connect | Connecting a wallet and requesting transaction approval |
| Your application | Validation, interface, error handling, and transaction monitoring |
Keeping these responsibilities separate makes the integration easier to test and upgrade.
Choose the right project setup
Before installing packages, decide where the SDK will run.
A browser dApp normally needs the SDK, the STON.fi API client, and TON Connect. A backend service may use the SDK and a TON RPC client without TON Connect, but it then needs a separate and carefully secured signing method if it sends transactions.
For a React application, a practical starting stack is:
- React with TypeScript
- Vite or Next.js
@ston-fi/sdk@ston-fi/api@ton/ton@tonconnect/ui-react
For a Node.js script, bot, or backend service, you can start with:
- TypeScript
-
tsxfor local execution @ston-fi/sdk@ston-fi/api@ton/ton
Do not install @ston-fi/omniston-sdk as a substitute for @ston-fi/sdk. Omniston is a separate aggregation protocol and package. It is appropriate when your application needs aggregated or cross-DEX execution, not when the goal is direct interaction with STON.fi DEX contracts.
Create the project and install the packages
The following example uses React, TypeScript, and Vite because it provides a small project that is easy to inspect.
1. Create the application
npm create vite@latest stonfi-sdk-starter -- --template react-ts
cd stonfi-sdk-starter
npm install
Start the untouched project once:
npm run dev
Opening the starter page before adding blockchain dependencies helps separate project setup problems from SDK configuration problems.
2. Install the STON.fi and TON packages
npm install @ston-fi/sdk @ston-fi/api @ton/ton @tonconnect/ui-react
The official SDK installation command is npm install @ston-fi/sdk. The additional packages provide API data, TON primitives, blockchain access, and wallet connection support required by a practical frontend integration.
The equivalent pnpm command is:
pnpm add @ston-fi/sdk @ston-fi/api @ton/ton @tonconnect/ui-react
For a backend-only TypeScript project, create a simpler environment:
mkdir stonfi-sdk-service
cd stonfi-sdk-service
npm init -y
npm install @ston-fi/sdk @ston-fi/api @ton/ton
npm install --save-dev typescript tsx @types/node
Add scripts to package.json:
{
"scripts": {
"dev": "tsx src/index.ts",
"typecheck": "tsc --noEmit",
"build": "tsc"
}
}
Package versions should normally be committed through your lockfile. Avoid copying old version numbers from tutorials because SDK examples can change when Router classes, factory helpers, or peer dependencies are updated.
Configure TypeScript and the browser runtime
The STON.fi SDK is designed for TypeScript, so strict compiler settings are useful. They catch incorrect addresses, missing transaction fields, and incompatible contract types before runtime.
A Vite React project already includes a suitable TypeScript configuration. For a standalone Node.js project, you can use:
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"outDir": "dist"
},
"include": ["src"]
}
Handling browser polyfills
TON libraries may use Node-compatible primitives such as Buffer. Some browser bundlers provide the required compatibility automatically, while others need an explicit polyfill.
For Vite, install:
npm install --save-dev vite-plugin-node-polyfills
Then update vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { nodePolyfills } from "vite-plugin-node-polyfills";
export default defineConfig({
plugins: [
react(),
nodePolyfills({
include: ["buffer"],
globals: {
Buffer: true,
},
}),
],
});
The official STON.fi React quickstart uses a Buffer polyfill in its Vite configuration. Add it when your build reports that Buffer is undefined or cannot be resolved, rather than adding unrelated Node polyfills without a reason.
Add environment variables
Create .env.local:
VITE_TON_RPC_ENDPOINT=https://toncenter.com/api/v2/jsonRPC
Add a type declaration in src/vite-env.d.ts if your project does not already provide one:
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_TON_RPC_ENDPOINT: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
Anything prefixed with VITE_ becomes visible in the browser bundle. Never place a private key, wallet mnemonic, or secret RPC credential in a Vite environment variable.
A public frontend can use a public endpoint or a restricted browser-safe credential. Sensitive API keys belong on a backend that your frontend accesses through controlled application endpoints.
Configure the blockchain and STON.fi clients
Create src/lib/stonfi.ts:
import { Client } from "@ston-fi/sdk";
import { StonApiClient } from "@ston-fi/api";
const endpoint = import.meta.env.VITE_TON_RPC_ENDPOINT;
if (!endpoint) {
throw new Error("VITE_TON_RPC_ENDPOINT is not configured");
}
export const tonClient = new Client({
endpoint,
});
export const stonApiClient = new StonApiClient();
These two clients solve different problems.
Client opens contract wrappers and reads data from TON through the configured RPC endpoint. StonApiClient talks to the STON.fi HTTP API and requires no configuration for its standard public endpoint. The API client can retrieve assets, pools, Routers, wallet positions, and simulation results.
Keeping both instances in one module prevents every component from creating its own client.
Discover the Router dynamically
Older examples often instantiate a specific Router class or copy a known contract address. That can work for controlled tests, but production applications should not assume that every asset pair uses the same Router version or pool type.
The current mainnet-first pattern is:
- Ask the STON.fi API to simulate the operation.
- Read the Router metadata returned by the simulation.
- Pass that metadata into
dexFactory(). - Open the generated Router contract with the blockchain client.
- Build transaction parameters from the same simulation values.
Create src/lib/prepareSwap.ts:
import { dexFactory } from "@ston-fi/sdk";
import { stonApiClient, tonClient } from "./stonfi";
type PrepareSwapInput = {
offerAddress: string;
askAddress: string;
offerUnits: string;
slippageTolerance?: string;
};
export async function prepareSwap({
offerAddress,
askAddress,
offerUnits,
slippageTolerance = "0.01",
}: PrepareSwapInput) {
const simulation = await stonApiClient.simulateSwap({
offerAddress,
askAddress,
offerUnits,
slippageTolerance,
});
const routerInfo = simulation.router;
const contracts = dexFactory(routerInfo);
const router = tonClient.open(
contracts.Router.create(routerInfo.address),
);
const proxyTon = contracts.pTON.create(
routerInfo.ptonMasterAddress,
);
return {
simulation,
router,
proxyTon,
};
}
The simulation result includes values such as the offered asset, requested asset, offered units, protected minimum output, and Router information. Reusing those values helps ensure that the transaction being constructed matches the route the application displayed to the user.
This file deliberately stops before building or sending a transaction. Installation and configuration should first prove that API access, Router discovery, contract creation, and TypeScript compilation all work.
Work with integer blockchain units
Do not pass human-readable decimal values directly into contract methods unless a specific helper explicitly accepts them.
A token interface might display 1.25, but the blockchain operation needs an integer based on that token's decimals. A token with six decimals represents 1.25 as 1250000 units, while a token with nine decimals represents it as 1250000000.
The asset metadata should determine the conversion. Avoid assuming that every jetton uses nine decimals.
Also avoid normal JavaScript floating-point arithmetic for financial amounts. Convert the user's string input into integer units, keep transaction amounts as strings or bigint, and only format them back into decimals for display.
Add TON Connect for wallet approval
The SDK prepares transaction parameters, but it should not receive a user's seed phrase or private key in a normal browser dApp. TON Connect provides the wallet connection and approval layer.
Create public/tonconnect-manifest.json:
{
"url": "https://your-domain.example",
"name": "STON.fi SDK Starter",
"iconUrl": "https://your-domain.example/icon-180.png"
}
For production, the manifest must be available through a public HTTPS URL. The wallet retrieves it to display the application's identity during connection. The icon should use a wallet-supported format such as PNG.
Wrap the application in src/main.tsx:
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { TonConnectUIProvider } from "@tonconnect/ui-react";
import App from "./App";
import "./index.css";
createRoot(document.getElementById("root")!).render(
<StrictMode>
<TonConnectUIProvider
manifestUrl={`${window.location.origin}/tonconnect-manifest.json`}
>
<App />
</TonConnectUIProvider>
</StrictMode>,
);
Add a connection button:
import { TonConnectButton } from "@tonconnect/ui-react";
export function WalletButton() {
return <TonConnectButton />;
}
TON Connect is the standard wallet connection protocol for TON dApps. It lets an application read the connected address and request transaction approval without taking possession of the wallet's keys. It does not replace the STON.fi SDK or the blockchain data client.
Verify the installation before building a swap
A useful first test is an API request that does not send a transaction.
Replace src/App.tsx temporarily:
import { useState } from "react";
import { TonConnectButton } from "@tonconnect/ui-react";
import { stonApiClient } from "./lib/stonfi";
export default function App() {
const [status, setStatus] = useState("Not tested");
const testConfiguration = async () => {
try {
setStatus("Loading STON.fi assets...");
const response = await stonApiClient.getAssets();
console.log("STON.fi asset response:", response);
setStatus("SDK environment is configured");
} catch (error) {
console.error(error);
setStatus(
error instanceof Error
? error.message
: "Configuration test failed",
);
}
};
return (
<main>
<h1>STON.fi SDK Starter</h1>
<TonConnectButton />
<button type="button" onClick={testConfiguration}>
Test configuration
</button>
<p>{status}</p>
</main>
);
}
Run the checks:
npm run dev
npm run build
The development server proves that the browser can load the modules. The production build is equally important because missing polyfills, module resolution problems, and environment variable mistakes sometimes appear only during bundling.
Before continuing, confirm that:
- the application compiles without TypeScript errors
- the asset request returns a response
- the wallet connection button opens
- the manifest loads from its expected URL
- no private data appears in the frontend bundle
- the production build completes successfully
Common configuration mistakes and production checks
One frequent mistake is treating the STON.fi API and the SDK as interchangeable. The API provides indexed data and simulations. The SDK creates smart contract objects and transaction messages. A production application normally needs both.
Another problem is mixing examples from different SDK generations. A v1 example may use DEX.v1.Router, while a current v2 workflow can use API Router metadata and dexFactory(). Check the documentation section and package version before copying a method name.
Watch for these additional issues:
- Hardcoded Router addresses: Resolve the mainnet Router from API metadata whenever possible.
- Mainnet and testnet mixing: The public STON.fi API serves mainnet data, so its Router information should not be combined with testnet assets or contracts.
- Unsafe decimal arithmetic: Convert display amounts into integer token units before simulation or transaction construction.
- Exposed secrets: Never place mnemonics, private keys, or unrestricted API credentials in browser code.
- Missing simulation: Generate and review a current simulation before constructing the transaction.
- Unverified token addresses: Symbols and names can be duplicated, so use verified asset addresses and metadata.
- No expiration strategy: Transaction requests should not remain valid indefinitely.
- No post-transaction tracking: A wallet acceptance response is not the same as confirmed on-chain execution.
A production-ready project should also log operation identifiers, display the minimum protected output, handle RPC and API timeouts, prevent duplicate submissions, and explain wallet rejection separately from blockchain failure.
Practical takeaway
A correct STON.fi SDK installation has four working layers: the STON.fi API can return current protocol data, the TON client can open the dynamically selected contracts, the SDK can build typed transaction parameters, and TON Connect can request wallet approval. Test each layer independently before combining them into a real swap. That approach makes configuration errors easier to identify and reduces the risk of signing a transaction built from stale or mismatched data.
Frequently Asked Questions
Is the STON.fi SDK only for TypeScript?
The SDK is written in TypeScript but can also be imported into JavaScript projects. TypeScript is preferable because contract methods contain many address, amount, and configuration fields that benefit from static checking. Even in a JavaScript application, the package's included type declarations can improve editor suggestions and reveal incorrect method usage.
Do I need @ston-fi/api to use @ston-fi/sdk?
Not for every low-level operation, but it is strongly recommended for production applications. The API provides asset information, pool data, simulations, and Router metadata. Without it, you may need to hardcode contract information and independently calculate or retrieve values that the API already exposes in a consistent format.
Why should I install @ton/ton?
The STON.fi SDK is built around TON contract primitives and blockchain client behavior. The @ton/ton package provides core types and utilities used across TON integrations. Installing it explicitly also helps the package manager resolve compatible peer dependencies and makes TON-specific imports available to the rest of your application.
Should a new integration use STON.fi v1 or v2?
A new integration should normally begin with the current v2 documentation and an API-driven Router selection flow. However, the Router returned for a particular operation should determine the contract classes your application opens. Do not force every operation through a manually selected version when dexFactory() can interpret the Router metadata.
Can the STON.fi SDK be tested on TON testnet?
Yes, but testnet configuration is more manual. The public STON.fi API provides mainnet protocol data, so its simulations and Router metadata should not be reused for testnet transactions. Testnet development may require known test contracts, suitable jettons, funded wallets, and pools with enough liquidity to exercise the intended operation.
Why does Vite report that Buffer is undefined?
Some TON dependencies use Node-compatible binary utilities, while browsers do not provide every Node global automatically. In a Vite project, adding vite-plugin-node-polyfills and enabling the Buffer polyfill usually resolves this specific issue. Add only the compatibility features your build needs rather than exposing a complete Node environment in the browser.
Does the SDK connect to the user's wallet?
No. The SDK prepares contract calls and transaction parameters. TON Connect, a wallet-specific SDK, or another signer sends those parameters for approval. In a standard non-custodial frontend, TON Connect allows the wallet to sign without revealing private keys to your application.
What is the minimum reliable setup for a STON.fi swap?
Use @ston-fi/api to simulate the swap, take the Router metadata from that result, pass it to dexFactory(), open the Router through the configured TON client, and generate transaction parameters from the simulated amounts. Finally, send those parameters through TON Connect and monitor the resulting on-chain operation instead of treating wallet approval as final settlement.
Sources and Further Reading
- STON.fi DEX SDK documentation - Installation, supported SDK generations, and links to version-specific contract guides
- STON.fi SDK v2 swap documentation - API-driven Router discovery,
dexFactory(), simulation data, and transaction preparation - STON.fi React swap quickstart - Complete frontend setup using the SDK, STON.fi API, TON Connect, Vite, and browser polyfills
- STON.fi SDK GitHub repository - Source code, package structure, supported contract wrappers, and the official Next.js demo application
- STON.fi API GitHub repository - Installation, zero-configuration client setup, and examples for assets, pools, Routers, farms, and operations
- STON.fi SDK npm package - Published package information and the official installation command
- TON Connect getting started guide - Manifest requirements, React packages, provider configuration, and wallet connection setup
- TON Connect overview - Wallet connection architecture, available packages, and the separation between wallet communication and blockchain integration







Top comments (1)
Thank you for reading to the end. If you spot any errors or inaccuracies in this article, please add your comment. You'll be very helpful to others who read this guide and encounter the same problems as you! Thank you very much!