@kaspacom/swap-sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 KASPACOM
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,246 @@
1
+ # Kaspa Swap SDK
2
+
3
+ A lightweight, headless swap SDK for Kaspa DeFi powered by Uniswap V2. Build your own UI and use the SDK to handle quotes, approvals, and swaps.
4
+
5
+
6
+ ## Features
7
+
8
+ - 🔄 Token swapping with Uniswap V2 protocol
9
+ - 💰 Support for ERC-20 tokens and native Kaspa wrappers
10
+ - 🎛️ Headless controller: bring your own UI
11
+ - 🔌 Simple wallet integration (EIP-1193 providers)
12
+ - ⚡ Real-time quote calculations
13
+ - 🛡️ Slippage protection and deadlines
14
+
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @kaspacom/swap-sdk
20
+ ```
21
+
22
+
23
+
24
+ ## Quick Start
25
+
26
+ ### Create the headless controller
27
+
28
+ ```typescript
29
+ import {
30
+ createKaspaComSwapController,
31
+ LoaderStatuses,
32
+ Erc20Token,
33
+ } from 'swap-widget';
34
+
35
+ const controller = createKaspaComSwapController({
36
+ networkConfig: 'kasplex-testnet',
37
+ walletProvider: window.ethereum, // any EIP-1193 provider
38
+ onChange: async (state, patch) => {
39
+ console.log('state changed', patch, state);
40
+ // Render your UI from state.computed, state.tradeInfo, state.loader, etc.
41
+ },
42
+ });
43
+ ```
44
+
45
+ ### Provide inputs and get a quote
46
+
47
+ ```typescript
48
+ const kas: Erc20Token = {
49
+ address: '0x0000000000000000000000000000000000000000',
50
+ symbol: 'KAS',
51
+ name: 'Kaspa',
52
+ decimals: 18,
53
+ };
54
+
55
+ const usdt: Erc20Token = {
56
+ address: '0xD33d07ccfEd8038cEd1aa393FbEf7D7dA72be20e',
57
+ symbol: 'USDT',
58
+ name: 'Tether',
59
+ decimals: 6,
60
+ };
61
+
62
+ await controller.setData({
63
+ fromToken: kas,
64
+ toToken: usdt,
65
+ amount: 1.0, // user-entered number
66
+ isOutputAmount: false, // false = amount is input; true = amount is desired output (How much the user will receive)
67
+ settings: { maxSlippage: '0.5', swapDeadline: 20 },
68
+ });
69
+
70
+ // Quote results are in controller.getState().computed
71
+ const { computed } = controller.getState();
72
+ console.log('computed amounts', computed);
73
+ ```
74
+
75
+ ### Connect wallet, approve if needed, and swap
76
+
77
+ ```typescript
78
+ await controller.connectWallet();
79
+
80
+ // Optional: call approve explicitly
81
+ await controller.approveIfNeeded();
82
+
83
+ // Perform the swap
84
+ const txHash = await controller.swap();
85
+ console.log('Swap TX hash:', txHash);
86
+ ```
87
+
88
+ ### Load tokens from the subgraph (for token pickers)
89
+
90
+ ```typescript
91
+ const tokens = await controller.getTokensFromGraph(100, 'kas');
92
+ console.log(tokens);
93
+ ```
94
+
95
+
96
+ ## API Reference
97
+
98
+ ### createKaspaComSwapController(options)
99
+ Creates and returns a `SwapSdkController` instance. Accepts either a preset string for `networkConfig` or a full `SwapSdkNetworkConfig` object.
100
+
101
+ - **options.networkConfig**: `'kasplex-testnet'` or `SwapSdkNetworkConfig`
102
+ - **options.walletProvider**: EIP-1193 provider (e.g., `window.ethereum`)
103
+ - **options.partnerKey?**: Optional partner key string
104
+ - **options.onChange?**: `(state, patch) => Promise<void>` callback invoked on any state change
105
+
106
+ Returns: `SwapSdkController`
107
+
108
+
109
+ ### class SwapSdkController
110
+
111
+ - **constructor(options: SwapSdkOptions)**: Normally use the factory `createKaspaComSwapController`.
112
+ - **connectWallet(injectedProvider?: Eip1193Provider): Promise<string>**
113
+ - Connects the wallet and sets signer on the swap service.
114
+ - Returns the connected address.
115
+ - **disconnectWallet(): void**
116
+ - Disconnects the wallet and clears signer.
117
+ - **getState(): SwapControllerOutput**
118
+ - Returns the current controller state.
119
+ - **setData(input: Partial<SwapControllerInput>): Promise<SwapControllerOutput>**
120
+ - Merges provided input, triggers a quote calculation if possible, and returns updated state.
121
+ - **calculateQuoteIfNeeded(): Promise<void>**
122
+ - Re-calculates quote if `fromToken`, `toToken`, and `amount` are valid.
123
+ - **approveIfNeeded(): Promise<string | undefined>**
124
+ - If allowance is insufficient, submits approval transaction and waits for confirmation.
125
+ - Returns approval transaction hash when submitted, otherwise `undefined` if already approved.
126
+ - **swap(): Promise<string>**
127
+ - Executes the swap using last computed trade info and amounts. Returns swap transaction hash.
128
+ - **getPartnerFee(): Promise<number>**
129
+ - Fetches the current partner fee in percentage (bps/divisor).
130
+ - **getTokensFromGraph(limit?: number, search?: string): Promise<any[]>**
131
+ - Queries the subgraph for tokens. Use for token lists/search.
132
+
133
+
134
+ ## Types
135
+
136
+ All types are exported from `swap-widget`.
137
+
138
+ - **Erc20Token**
139
+ - `address: string`
140
+ - `symbol: string`
141
+ - `name: string`
142
+ - `decimals: number`
143
+
144
+ - **SwapSettings**
145
+ - `maxSlippage: string` (e.g., `'0.5'` for 0.5%)
146
+ - `swapDeadline: number` (minutes)
147
+
148
+ - **SwapSdkOptions**
149
+ - `networkConfig: SwapSdkNetworkConfig | string`
150
+ - `walletProvider: any` (EIP-1193)
151
+ - `partnerKey?: string`
152
+ - `onChange?: (state: SwapControllerOutput, patch: Partial<SwapControllerOutput>) => Promise<void>`
153
+
154
+ - **SwapControllerInput** (used with `setData`)
155
+ - `fromToken?: Erc20Token | null`
156
+ - `toToken?: Erc20Token | null`
157
+ - `amount?: number` (user-entered number)
158
+ - `isOutputAmount?: boolean` (false = `amount` is input; true = `amount` is desired output)
159
+ - `settings?: Partial<SwapSettings>`
160
+
161
+ - **LoaderStatuses**
162
+ - `CALCULATING_QUOTE = 1`
163
+ - `APPROVING = 2`
164
+ - `SWAPPING = 3`
165
+
166
+ - **ComputedAmounts** (found in `SwapControllerOutput.computed`)
167
+
168
+ - `amountIn: string`
169
+ The input amount as entered by the user, formatted for display.
170
+
171
+ - `amountOut: string`
172
+ The output amount as calculated for the user, formatted for display.
173
+
174
+ - `amountInRaw: string`
175
+ The exact input amount (in smallest token units, e.g. wei) that will be sent to the swap contract.
176
+
177
+ - `amountOutRaw: string`
178
+ The exact output amount (in smallest token units, e.g. wei) that will be received from the swap contract.
179
+
180
+ - `maxAmountIn?: string`
181
+ (Optional) The maximum input amount the user need to send to receive the desired output amount. Only present if `isOutputAmount` is `true`.
182
+
183
+ - `minAmountOut?: string`
184
+ (Optional) The minimum output amount the user will receive, accounting for slippage. Only present if `isOutputAmount` is `false`.
185
+
186
+ - `maxAmountInRaw?: string`
187
+ (Optional) The raw (smallest units) value of `maxAmountIn`.
188
+
189
+ - `minAmountOutRaw?: string`
190
+ (Optional) The raw (smallest units) value of `minAmountOut`.
191
+
192
+ - **SwapControllerOutput**
193
+ - `error?: string`
194
+ - `txHash?: string` (Swap tx hash)
195
+ - `approveTxHash?: string` (Approval transaction tx hash)
196
+ - `tradeInfo?: Trade<Currency, Currency, TradeType>` (Uniswap V2 trade)
197
+ - `computed?: ComputedAmounts`
198
+ - `loader: LoaderStatuses | null`
199
+
200
+ - **SwapSdkNetworkConfig** (also see presets in `NETWORKS`)
201
+ - `name: string`
202
+ - `chainId: number`
203
+ - `rpcUrl: string`
204
+ - `routerAddress: string`
205
+ - `factoryAddress: string`
206
+ - `proxyAddress?: string`
207
+ - `wethAddress: string`
208
+ - `graphEndpoint: string`
209
+ - `blockExplorerUrl?: string`
210
+ - `additionalJsonRpcApiProviderOptionsOptions?: any`
211
+
212
+ - **NETWORKS**
213
+ - Preset map of network keys to `SwapSdkNetworkConfig` objects. Includes `'kasplex-testnet'`.
214
+
215
+
216
+ ## Usage Patterns
217
+
218
+ - **Exact input vs exact output**
219
+ - Set `isOutputAmount` to `false` to quote "sell X get best Y".
220
+ - Set `isOutputAmount` to `true` to quote "get exactly X spend up to Y".
221
+ - **React integration**
222
+ - Call `setData` on input changes; render from `controller.getState()`.
223
+ - Use `state.loader` to show spinners: `LoaderStatuses.CALCULATING_QUOTE`, `APPROVING`, `SWAPPING`.
224
+
225
+
226
+ ## Development
227
+
228
+ ```bash
229
+ git clone https://github.com/kaspacom/swap-widget.git
230
+ cd swap-widget
231
+ npm install
232
+ npm run build
233
+ ```
234
+
235
+
236
+ ## License
237
+
238
+ MIT License - see `LICENSE`.
239
+
240
+
241
+ ## Support
242
+
243
+ - Open an issue on GitHub
244
+ - Join our Telegram: https://t.me/KaspaComOfficial
245
+
246
+
@@ -0,0 +1,23 @@
1
+ import { SwapSdkOptions, SwapControllerOutput, SwapControllerInput } from '../types';
2
+ import { Eip1193Provider } from 'ethers';
3
+ export declare class SwapSdkController {
4
+ private walletService;
5
+ private swapService;
6
+ private state;
7
+ private input;
8
+ private options;
9
+ constructor(options: SwapSdkOptions);
10
+ private initServices;
11
+ private setChange;
12
+ connectWallet(injectedProvider?: Eip1193Provider): Promise<string>;
13
+ disconnectWallet(): void;
14
+ getState(): SwapControllerOutput;
15
+ private get settings();
16
+ calculateQuoteIfNeeded(): Promise<void>;
17
+ setData(input: Partial<SwapControllerInput>): Promise<SwapControllerOutput>;
18
+ approveIfNeeded(): Promise<string | undefined>;
19
+ swap(): Promise<string>;
20
+ getPartnerFee(): Promise<number>;
21
+ getTokensFromGraph(limit?: number, search?: string): Promise<import("../types").Erc20Token[]>;
22
+ }
23
+ //# sourceMappingURL=swap-sdk.controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap-sdk.controller.d.ts","sourceRoot":"","sources":["../../src/controllers/swap-sdk.controller.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EAEd,oBAAoB,EACpB,mBAAmB,EAEpB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAOzC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,WAAW,CAA0B;IAE7C,OAAO,CAAC,KAAK,CAEX;IAIF,OAAO,CAAC,KAAK,CAMX;IAIF,OAAO,CAAC,OAAO,CAAiB;gBAEpB,OAAO,EAAE,cAAc;IAMnC,OAAO,CAAC,YAAY;YAaN,SAAS;IAWjB,aAAa,CAAC,gBAAgB,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC;IAOxE,gBAAgB,IAAI,IAAI;IAKxB,QAAQ,IAAI,oBAAoB;IAIhC,OAAO,KAAK,QAAQ,GAKnB;IAGK,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BvC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAY3E,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAmC9C,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC;IA2DvB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,kBAAkB,CAAC,KAAK,GAAE,MAAY,EAAE,MAAM,CAAC,EAAE,MAAM;CAO9D"}
@@ -0,0 +1,166 @@
1
+ import { WalletService } from '../services/wallet.service';
2
+ import { PARTNER_FEE_BPS_DIVISOR, SwapService } from '../services/swap.service';
3
+ import { LoaderStatuses, } from '../types';
4
+ const DEFAULT_SETTINGS = {
5
+ maxSlippage: '0.5',
6
+ swapDeadline: 20,
7
+ };
8
+ export class SwapSdkController {
9
+ constructor(options) {
10
+ this.state = {
11
+ loader: null,
12
+ };
13
+ this.input = {
14
+ fromToken: null,
15
+ toToken: null,
16
+ amount: undefined,
17
+ isOutputAmount: false,
18
+ settings: DEFAULT_SETTINGS,
19
+ };
20
+ this.options = options;
21
+ this.initServices();
22
+ }
23
+ initServices() {
24
+ this.walletService = new WalletService(this.options.networkConfig, this.options.walletProvider);
25
+ this.swapService = new SwapService(this.walletService.getProvider(), this.options.networkConfig, this.options);
26
+ }
27
+ async setChange(patch) {
28
+ const next = {
29
+ ...this.state,
30
+ ...patch,
31
+ };
32
+ this.state = next;
33
+ if (typeof this.options.onChange === 'function') {
34
+ await this.options.onChange(next, patch);
35
+ }
36
+ }
37
+ async connectWallet(injectedProvider) {
38
+ const address = await this.walletService.connect(injectedProvider);
39
+ const signer = this.walletService.getSigner();
40
+ if (signer)
41
+ this.swapService.setSigner(signer);
42
+ return address;
43
+ }
44
+ disconnectWallet() {
45
+ this.walletService.disconnect();
46
+ this.swapService.setSigner(null);
47
+ }
48
+ getState() {
49
+ return this.state;
50
+ }
51
+ get settings() {
52
+ return {
53
+ ...DEFAULT_SETTINGS,
54
+ ...(this.input.settings || {}),
55
+ };
56
+ }
57
+ async calculateQuoteIfNeeded() {
58
+ const { fromToken, toToken, amount, isOutputAmount } = this.input;
59
+ if (!fromToken || !toToken || !amount || amount <= 0) {
60
+ return;
61
+ }
62
+ // Set loader to calculating
63
+ await this.setChange({ loader: LoaderStatuses.CALCULATING_QUOTE, error: undefined });
64
+ try {
65
+ // Use the calculateTrade method which returns both trade and computed amounts
66
+ const tradeResult = await this.swapService.calculateTrade(fromToken, toToken, String(amount), isOutputAmount == true, // isOutputAmount: true for input amount, false for output amount
67
+ this.settings.maxSlippage);
68
+ await this.setChange({
69
+ computed: tradeResult.computed,
70
+ tradeInfo: tradeResult.trade,
71
+ loader: null,
72
+ });
73
+ }
74
+ catch (error) {
75
+ await this.setChange({ error: error?.message || String(error), loader: null });
76
+ }
77
+ }
78
+ async setData(input) {
79
+ // Merge input and settings
80
+ this.input = {
81
+ ...this.input,
82
+ ...input,
83
+ };
84
+ await this.calculateQuoteIfNeeded();
85
+ return this.getState();
86
+ }
87
+ async approveIfNeeded() {
88
+ if (!this.input || !this.walletService.isConnected())
89
+ throw new Error('Wallet not connected or input missing');
90
+ const { fromToken, amount } = this.input;
91
+ if (!fromToken || amount === undefined || !this.state.computed?.amountInRaw)
92
+ throw new Error('fromToken or amount missing');
93
+ await this.setChange({ loader: LoaderStatuses.APPROVING });
94
+ try {
95
+ const tx = await this.swapService?.approveIfNeedApproval(fromToken, BigInt(this.state.computed.amountInRaw));
96
+ let receipt;
97
+ if (tx) {
98
+ await this.setChange({ approveTxHash: tx.hash });
99
+ receipt = await tx.wait();
100
+ if (!receipt) {
101
+ throw new Error("Receipt not found, Please try again");
102
+ }
103
+ if (receipt.status != 1) {
104
+ throw new Error("Transaction Rejected");
105
+ }
106
+ }
107
+ return receipt?.hash;
108
+ }
109
+ catch (error) {
110
+ await this.setChange({ error: error?.message || String(error), loader: null });
111
+ throw error;
112
+ }
113
+ }
114
+ async swap() {
115
+ try {
116
+ await this.setChange({
117
+ txHash: undefined,
118
+ approveTxHash: undefined,
119
+ });
120
+ const { fromToken, toToken, amount } = this.input;
121
+ if (!fromToken || !toToken || amount === undefined)
122
+ throw new Error('Tokens or amount not set');
123
+ await this.approveIfNeeded();
124
+ await this.setChange({ loader: LoaderStatuses.SWAPPING });
125
+ // Get the trade path from the tradeInfo
126
+ const trade = this.state.tradeInfo;
127
+ if (!trade)
128
+ throw new Error('Trade info missing - calculate quote first');
129
+ // Extract path from the trade route
130
+ const path = trade.route.path.map(token => token.address);
131
+ if (path.length === 0)
132
+ throw new Error('Trade path missing');
133
+ // Use the computed amounts for the swap
134
+ const computed = this.state.computed;
135
+ if (!computed)
136
+ throw new Error('Computed amounts missing');
137
+ const transaction = await this.swapService.swapTokens(fromToken, toToken, computed.maxAmountInRaw || computed.amountInRaw, computed.minAmountOutRaw || computed.amountOutRaw, path, this.input.isOutputAmount == true, this.settings.swapDeadline);
138
+ await this.setChange({ txHash: transaction.hash });
139
+ const receipt = await transaction.wait();
140
+ if (!receipt) {
141
+ throw new Error("Receipt not found, Please try again");
142
+ }
143
+ if (receipt.status != 1) {
144
+ throw new Error("Transaction Rejected");
145
+ }
146
+ await this.setChange({
147
+ loader: null,
148
+ });
149
+ return receipt.hash;
150
+ }
151
+ catch (error) {
152
+ await this.setChange({ error: error?.message || String(error), loader: null });
153
+ throw error;
154
+ }
155
+ }
156
+ async getPartnerFee() {
157
+ return Number(await this.swapService.loadPartnerFee()) / Number(PARTNER_FEE_BPS_DIVISOR);
158
+ }
159
+ async getTokensFromGraph(limit = 100, search) {
160
+ if (!this.swapService) {
161
+ throw new Error('Swap Service not exists');
162
+ }
163
+ return await this.swapService.getTokensFromGraph(limit, search);
164
+ }
165
+ }
166
+ //# sourceMappingURL=swap-sdk.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap-sdk.controller.js","sourceRoot":"","sources":["../../src/controllers/swap-sdk.controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export * from './types';
2
+ export { WalletService } from './services/wallet.service';
3
+ export { SwapService } from './services/swap.service';
4
+ import { SwapSdkController } from './controllers/swap-sdk.controller';
5
+ export { SwapSdkController } from './controllers/swap-sdk.controller';
6
+ import { SwapSdkOptions } from './types';
7
+ /**
8
+ * Create a new headless swap controller
9
+ * @param options Configuration options for the controller
10
+ * @returns SwapSdkController instance
11
+ */
12
+ export declare function createKaspaComSwapController(options: SwapSdkOptions): SwapSdkController;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAGtE,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAGzC;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,cAAc,GAAG,iBAAiB,CAWvF"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ // Export types
2
+ export * from './types';
3
+ // Export services
4
+ export { WalletService } from './services/wallet.service';
5
+ export { SwapService } from './services/swap.service';
6
+ // Export headless controller only
7
+ import { SwapSdkController } from './controllers/swap-sdk.controller';
8
+ export { SwapSdkController } from './controllers/swap-sdk.controller';
9
+ import { NETWORKS } from './types/networks';
10
+ /**
11
+ * Create a new headless swap controller
12
+ * @param options Configuration options for the controller
13
+ * @returns SwapSdkController instance
14
+ */
15
+ export function createKaspaComSwapController(options) {
16
+ let resolvedOptions;
17
+ if ('networkConfig' in options && typeof options.networkConfig === 'string') {
18
+ const networkConfig = NETWORKS[options.networkConfig];
19
+ if (!networkConfig)
20
+ throw new Error(`Unknown network key: ${options.networkConfig}`);
21
+ resolvedOptions = { ...options, networkConfig };
22
+ }
23
+ else {
24
+ resolvedOptions = options;
25
+ }
26
+ return new SwapSdkController(resolvedOptions);
27
+ }
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,eAAe;AACf,cAAc,SAAS,CAAC;AAExB,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,kCAAkC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAItE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAuB;IAClE,IAAI,eAA+B,CAAC;IACpC,IAAI,eAAe,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,aAAa,KAAK,QAAQ,EAAE,CAAC;QAC5E,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACtD,IAAI,CAAC,aAAa;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;QACrF,eAAe,GAAG,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,CAAC;IAClD,CAAC;SAAM,CAAC;QACN,eAAe,GAAG,OAAyB,CAAC;IAC9C,CAAC;IAED,OAAO,IAAI,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,103 @@
1
+ import { Signer, BrowserProvider, JsonRpcProvider, ContractTransactionResponse, TransactionResponse } from 'ethers';
2
+ import { Currency, Token, TradeType } from '@uniswap/sdk-core';
3
+ import { Trade, Pair } from '@uniswap/v2-sdk';
4
+ import { ComputedAmounts, Erc20Token, SwapSdkOptions } from '../types';
5
+ import { SwapSdkNetworkConfig } from '../types/networks';
6
+ export declare const PARTNER_FEE_BPS_DIVISOR = 10000n;
7
+ export declare class SwapService {
8
+ private config;
9
+ private swapOptions;
10
+ private provider;
11
+ private signer;
12
+ private routerContract;
13
+ private factoryContract;
14
+ private proxyContract?;
15
+ private wethAddress;
16
+ private chainId;
17
+ private pairs;
18
+ private pairsLoadedPromise;
19
+ private resolvePairsLoaded;
20
+ private partnerFeeLoadedPromise;
21
+ private resolvePartnerFeeLoaded;
22
+ private partnerFee;
23
+ private isFeeActive;
24
+ private wethToken;
25
+ constructor(provider: BrowserProvider | JsonRpcProvider, config: SwapSdkNetworkConfig, swapOptions: SwapSdkOptions);
26
+ loadPartnerFee(): Promise<bigint>;
27
+ setSigner(signer: Signer): void;
28
+ /**
29
+ * Rounds a number string to the specified number of decimal places
30
+ * to avoid parseUnits errors with too many decimals
31
+ */
32
+ private roundToDecimals;
33
+ /**
34
+ * Loads all pairs from The Graph and caches them as Uniswap SDK Pair instances.
35
+ * @param graphEndpoint The GraphQL endpoint URL
36
+ */
37
+ loadAllPairsFromGraph(): Promise<void>;
38
+ waitForPairsLoaded(): Promise<void>;
39
+ waitForPartnerFeeLoaded(): Promise<void>;
40
+ createSDKPair(pair: {
41
+ id: string;
42
+ token0: {
43
+ id: string;
44
+ symbol: string;
45
+ name: string;
46
+ decimals: string | number;
47
+ };
48
+ token1: {
49
+ id: string;
50
+ symbol: string;
51
+ name: string;
52
+ decimals: string | number;
53
+ };
54
+ reserve0?: string;
55
+ reserve1?: string;
56
+ positionValueUsd?: number;
57
+ totalTokens?: number;
58
+ }): Pair;
59
+ /**
60
+ * Returns the cached pairs for use in routing.
61
+ */
62
+ getPairs(): Pair[];
63
+ /**
64
+ * Finds the best trade path using Uniswap SDK for a given input amount.
65
+ * Returns the best path as an array of addresses, or null if no trade found.
66
+ */
67
+ private getBestTrade;
68
+ private trimTrailingZeros;
69
+ /**
70
+ *
71
+ * @param sellToken
72
+ * @param buyToken
73
+ * @param targetAmount
74
+ * @param isOutputAmount true if user input output (How much tokens to receive) and not input (how much tokens to sell)
75
+ * @param slippage
76
+ * @returns
77
+ */
78
+ calculateTrade(sellToken: Erc20Token, buyToken: Erc20Token, targetAmount: string, isOutputAmount: boolean, slippage: string): Promise<{
79
+ trade: Trade<Currency, Currency, TradeType.EXACT_INPUT> | Trade<Currency, Currency, TradeType.EXACT_OUTPUT>;
80
+ computed: ComputedAmounts;
81
+ }>;
82
+ checkApproval(tokenAddress: string, amount: string, spenderAddress: string): Promise<boolean>;
83
+ approveIfNeedApproval(fromToken: Erc20Token, amountInWei: bigint): Promise<ContractTransactionResponse | null>;
84
+ swapTokens(fromToken: Erc20Token, toToken: Erc20Token, amountInWei: string, amountOutWei: string, path: string[], isOutputAmount: boolean, deadline: number): Promise<TransactionResponse>;
85
+ getPairAddress(tokenA: string, tokenB: string): Promise<string>;
86
+ checkLiquidityExists(tokenA: string, tokenB: string): Promise<boolean>;
87
+ createTrade(fromToken: Erc20Token, toToken: Erc20Token, amountIn: string, slippageTolerance?: number): Promise<Trade<Token, Token, TradeType>>;
88
+ /**
89
+ * Fetch tokens from the graph endpoint (subgraph)
90
+ * @param graphEndpoint The GraphQL endpoint URL
91
+ * @param search Optional search string for symbol or name
92
+ */
93
+ getTokensFromGraph(limit?: number, search?: string): Promise<Erc20Token[]>;
94
+ /**
95
+ * Concatenates bytes: selector, array of bytes (each element is Uint8Array), array length (uint8, 1 byte), marker (bytes16(keccak256(markerString)))
96
+ * @param selectorBytes Uint8Array — function selector (usually 4 bytes)
97
+ * @param arrayOfBytes Uint8Array[] — array of bytes (each element is Uint8Array)
98
+ * @param markerString string — string from which bytes16(keccak256(...)) will be derived
99
+ * @returns Uint8Array — concatenated result
100
+ */
101
+ private concatSelectorAndParams;
102
+ }
103
+ //# sourceMappingURL=swap.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swap.service.d.ts","sourceRoot":"","sources":["../../src/services/swap.service.ts"],"names":[],"mappings":"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"}