@tomo-inc/transaction-builder-sdk 0.0.1-alpha.2 → 0.0.1

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/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@tomo-inc/transaction-builder-sdk",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1",
4
4
  "author": "tomo.inc",
5
+ "files": [
6
+ "dist/**/*",
7
+ "README.md",
8
+ "CHANGELOG.md"
9
+ ],
5
10
  "private": false,
6
11
  "main": "./dist/index.cjs",
7
12
  "module": "./dist/index.mjs",
@@ -21,10 +26,10 @@
21
26
  "tronweb": "^6.0.3"
22
27
  },
23
28
  "devDependencies": {
24
- "@tomo-inc/tomo-api": "workspace:*",
25
29
  "@types/node": "^20.11.19",
26
30
  "tsup": "^8.3.5",
27
31
  "typescript": "^5.3.3",
28
- "vitest": "^3.0.8"
32
+ "vitest": "^3.0.8",
33
+ "@tomo-inc/tomo-api": "0.0.2"
29
34
  }
30
- }
35
+ }
package/project.json DELETED
@@ -1,52 +0,0 @@
1
- {
2
- "name": "transaction-builder-sdk",
3
- "sourceRoot": "packages/transaction-builder-sdk/src",
4
- "projectType": "library",
5
- "targets": {
6
- "build": {
7
- "executor": "nx:run-commands",
8
- "outputs": ["{projectRoot}/dist"],
9
- "options": {
10
- "command": "tsup",
11
- "cwd": "packages/transaction-builder-sdk"
12
- }
13
- },
14
- "dev": {
15
- "executor": "nx:run-commands",
16
- "options": {
17
- "command": "tsup --watch",
18
- "cwd": "packages/transaction-builder-sdk"
19
- }
20
- },
21
- "test": {
22
- "executor": "nx:run-commands",
23
- "outputs": ["{projectRoot}/coverage"],
24
- "options": {
25
- "command": "vitest run --typecheck=false src/__tests__/business.test.ts",
26
- "cwd": "packages/transaction-builder-sdk"
27
- }
28
- },
29
- "version:up": {
30
- "executor": "nx:run-commands",
31
- "options": {
32
- "command": "npm version patch --no-git-tag-version",
33
- "cwd": "packages/transaction-builder-sdk"
34
- }
35
- },
36
- "lint": {
37
- "executor": "nx:run-commands",
38
- "options": {
39
- "command": "eslint src/",
40
- "cwd": "packages/transaction-builder-sdk"
41
- }
42
- },
43
- "type-check": {
44
- "executor": "nx:run-commands",
45
- "options": {
46
- "command": "tsc --noEmit",
47
- "cwd": "packages/transaction-builder-sdk"
48
- }
49
- }
50
- },
51
- "tags": ["scope:transaction-builder", "type:library"]
52
- }
@@ -1,315 +0,0 @@
1
- // __tests__/business.integration.test.ts
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
3
- import { Business, Chain, TransactionQuoteParams, TransactionQuoteResult, TransactionToken } from "../";
4
- import { IPlatformType } from "../types/chain";
5
-
6
- describe("Business Integration", () => {
7
- let business: Business;
8
- let mockEthChain: Chain;
9
- let mockBscChain: Chain;
10
- let mockEthToken: TransactionToken;
11
- let mockBnbToken: TransactionToken;
12
- let mockDaiToken: TransactionToken;
13
- let mockBridgeQuoteParams: TransactionQuoteParams;
14
- let mockSwapQuoteParams: TransactionQuoteParams;
15
-
16
- beforeEach(() => {
17
- business = new Business({
18
- config: {
19
- API_KEY: "j7sjxxdv5iaqnq69ull0t1rbcc3y6yx5",
20
- API_SECRET: "7bk63t810l3czi7b6vvd6gpxlqsq8ype",
21
- SALT: "Tomo@2025!@#",
22
- CLIENT_ID: "",
23
- },
24
- tomoStage: "dev",
25
- });
26
-
27
- // Setup mock chains
28
- mockEthChain = {
29
- chainName: "Ethereum",
30
- chainId: 1,
31
- chainIndex: 100,
32
- orderStatusSupport: true,
33
- support: true,
34
- isListed: true,
35
- type: 1,
36
- name: "ETH",
37
- nativeCurrencyName: "ETH",
38
- nativeCurrencySymbol: "ETH",
39
- nativeCurrencyDecimals: 18,
40
- platformType: IPlatformType.EVM,
41
- icon: "https://example.com/eth.png",
42
- supportSwap: true,
43
- isTestnet: false,
44
- };
45
-
46
- mockBscChain = {
47
- chainName: "BNB Smart Chain",
48
- chainId: 56,
49
- chainIndex: 5600,
50
- orderStatusSupport: true,
51
- support: true,
52
- isListed: true,
53
- type: 1,
54
- name: "BSC",
55
- nativeCurrencyName: "BNB",
56
- nativeCurrencySymbol: "BNB",
57
- nativeCurrencyDecimals: 18,
58
- platformType: IPlatformType.EVM,
59
- icon: "https://example.com/bnb.png",
60
- supportSwap: true,
61
- isTestnet: false,
62
- };
63
-
64
- // Setup mock tokens
65
- mockEthToken = {
66
- address: "",
67
- chain: mockEthChain,
68
- };
69
-
70
- mockBnbToken = {
71
- address: "",
72
- chain: mockBscChain,
73
- };
74
-
75
- mockDaiToken = {
76
- address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
77
- chain: mockEthChain,
78
- };
79
-
80
- // Setup mock quote parameters
81
- mockBridgeQuoteParams = {
82
- sender: "0x1234567890123456789012345678901234567890",
83
- recipient: "0x1234567890123456789012345678901234567890",
84
- fromToken: mockEthToken,
85
- toToken: mockBnbToken,
86
- slippage: 0.5,
87
- amount: "1000000000000000000", // 1 ETH
88
- };
89
-
90
- mockSwapQuoteParams = {
91
- sender: "0x1234567890123456789012345678901234567890",
92
- recipient: "0x1234567890123456789012345678901234567890",
93
- fromToken: mockEthToken,
94
- toToken: mockDaiToken,
95
- slippage: 0.5,
96
- amount: "1000000000000000000", // 1 ETH
97
- };
98
- });
99
-
100
- describe("Bridge Flow", () => {
101
- it("should get bridge quotes and build bridge transaction", async () => {
102
- // Mock the getBridgeQuotes implementation to return a quote result
103
- const mockBridgeQuotes: TransactionQuoteResult[] = [
104
- {
105
- quoteID: "bridge-quote-123",
106
- amountIn: "1000000000000000000",
107
- amountOut: "995000000000000000",
108
- contract: "0xBridgeContractAddress",
109
- amountOutMin: "990000000000000000",
110
- gasNetWorkFee: "21000",
111
- approveGasFee: "50000",
112
- crossNetworkFee: {
113
- fromChainNetworkFee: "0",
114
- toChainNetworkFee: "0",
115
- providerServiceFee: "0",
116
- },
117
- dexInfo: {
118
- name: "MockBridge",
119
- displayName: "Mock Bridge",
120
- logo: "https://example.com/bridge.png",
121
- },
122
- fromToken: {
123
- chainID: "1",
124
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
125
- symbol: "ETH",
126
- decimals: 18,
127
- },
128
- toToken: {
129
- chainID: "56",
130
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
131
- symbol: "BNB",
132
- decimals: 18,
133
- },
134
- extended: {
135
- requestID: "bridge-request-123",
136
- },
137
- routes: [
138
- {
139
- amountIn: "1000000000000000000",
140
- amountOut: "995000000000000000",
141
- paths: [
142
- {
143
- dexProvider: "MockBridge",
144
- fromToken: {
145
- chainID: "1",
146
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
147
- symbol: "ETH",
148
- decimals: 18,
149
- },
150
- toToken: {
151
- chainID: "56",
152
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
153
- symbol: "BNB",
154
- decimals: 18,
155
- },
156
- amountIn: "1000000000000000000",
157
- amountOut: "995000000000000000",
158
- },
159
- ],
160
- },
161
- ],
162
- estimatedGas: {
163
- feeUSD: "1.50",
164
- gasLimit: "21000",
165
- baseFee: "30",
166
- priorityFee: {
167
- low: "1",
168
- medium: "2",
169
- high: "3",
170
- },
171
- },
172
- },
173
- ];
174
-
175
- // Mock the bridgeBuilder implementation to return a transaction
176
- const mockBridgeTransaction = {
177
- chainId: "0x1",
178
- data: "0xBridgeTransactionData",
179
- gasLimit: "21000",
180
- to: "0xBridgeContractAddress",
181
- from: "0xUserAddress",
182
- value: "0x0",
183
- nonce: "0x1",
184
- };
185
-
186
- // Mock the implementations
187
- vi.spyOn(business, "getBridgeQuotes").mockResolvedValue(mockBridgeQuotes);
188
- vi.spyOn(business, "bridgeBuilder").mockResolvedValue(mockBridgeTransaction);
189
-
190
- // Execute the flow: get quotes then build transaction
191
- const quotes = await business.getBridgeQuotes(mockBridgeQuoteParams);
192
- const transaction = await business.bridgeBuilder(quotes[0], mockBridgeQuoteParams);
193
-
194
- // Verify the flow
195
- expect(quotes).toHaveLength(1);
196
- expect(quotes[0]).toHaveProperty("quoteID", "bridge-quote-123");
197
- expect(quotes[0]).toHaveProperty("amountIn", "1000000000000000000");
198
-
199
- expect(transaction).toHaveProperty("data", "0xBridgeTransactionData");
200
- expect(transaction).toHaveProperty("to", "0xBridgeContractAddress");
201
-
202
- // Verify both methods were called
203
- expect(business.getBridgeQuotes).toHaveBeenCalledWith(mockBridgeQuoteParams);
204
- expect(business.bridgeBuilder).toHaveBeenCalledWith(quotes[0], mockBridgeQuoteParams);
205
- });
206
- });
207
-
208
- describe("Swap Flow", () => {
209
- it("should get swap quotes and build swap transaction", async () => {
210
- // Mock the getSwapQuotes implementation to return a quote result
211
- const mockSwapQuotes: TransactionQuoteResult[] = [
212
- {
213
- quoteID: "swap-quote-123",
214
- amountIn: "1000000000000000000",
215
- amountOut: "3000000000000000000000",
216
- contract: "0xSwapContractAddress",
217
- amountOutMin: "2985000000000000000000",
218
- gasNetWorkFee: "150000",
219
- approveGasFee: "50000",
220
- crossNetworkFee: {
221
- fromChainNetworkFee: "0",
222
- toChainNetworkFee: "0",
223
- providerServiceFee: "0",
224
- },
225
- dexInfo: {
226
- name: "Uniswap",
227
- displayName: "Uniswap V3",
228
- logo: "https://example.com/uniswap.png",
229
- },
230
- fromToken: {
231
- chainID: "1",
232
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
233
- symbol: "ETH",
234
- decimals: 18,
235
- },
236
- toToken: {
237
- chainID: "1",
238
- address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
239
- symbol: "DAI",
240
- decimals: 18,
241
- },
242
- extended: {
243
- requestID: "swap-request-123",
244
- },
245
- routes: [
246
- {
247
- amountIn: "1000000000000000000",
248
- amountOut: "3000000000000000000000",
249
- paths: [
250
- {
251
- dexProvider: "Uniswap",
252
- fromToken: {
253
- chainID: "1",
254
- address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
255
- symbol: "ETH",
256
- decimals: 18,
257
- },
258
- toToken: {
259
- chainID: "1",
260
- address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
261
- symbol: "DAI",
262
- decimals: 18,
263
- },
264
- amountIn: "1000000000000000000",
265
- amountOut: "3000000000000000000000",
266
- },
267
- ],
268
- },
269
- ],
270
- estimatedGas: {
271
- feeUSD: "5.25",
272
- gasLimit: "150000",
273
- baseFee: "35",
274
- priorityFee: {
275
- low: "1",
276
- medium: "2",
277
- high: "3",
278
- },
279
- },
280
- },
281
- ];
282
-
283
- // Mock the swapBuilder implementation to return a transaction
284
- const mockSwapTransaction = {
285
- chainId: "0x1",
286
- data: "0xSwapTransactionData",
287
- gasLimit: "150000",
288
- to: "0xSwapContractAddress",
289
- from: "0xUserAddress",
290
- value: "0x0",
291
- nonce: "0x2",
292
- };
293
-
294
- // Mock the implementations
295
- vi.spyOn(business, "getSwapQuotes").mockResolvedValue(mockSwapQuotes);
296
- vi.spyOn(business, "swapBuilder").mockResolvedValue(mockSwapTransaction);
297
-
298
- // Execute the flow: get quotes then build transaction
299
- const quotes = await business.getSwapQuotes(mockSwapQuoteParams);
300
- const transaction = await business.swapBuilder(quotes[0], mockSwapQuoteParams);
301
-
302
- // Verify the flow
303
- expect(quotes).toHaveLength(1);
304
- expect(quotes[0]).toHaveProperty("quoteID", "swap-quote-123");
305
- expect(quotes[0]).toHaveProperty("amountOut", "3000000000000000000000");
306
-
307
- expect(transaction).toHaveProperty("data", "0xSwapTransactionData");
308
- expect(transaction).toHaveProperty("gasLimit", "150000");
309
-
310
- // Verify both methods were called
311
- expect(business.getSwapQuotes).toHaveBeenCalledWith(mockSwapQuoteParams);
312
- expect(business.swapBuilder).toHaveBeenCalledWith(quotes[0], mockSwapQuoteParams);
313
- });
314
- });
315
- });
package/src/api/index.ts DELETED
@@ -1,115 +0,0 @@
1
- import { utils } from "@tomo-inc/tomo-api";
2
- import axios from "axios";
3
- import { ApiConfig, Config, TomoStage } from "../types";
4
- import { TransactionQuoteResult } from "../types/swap";
5
- import stageConfig from "./../constant/stage.json";
6
- import { IRawApiToken, SwapApiRouterTxRequestV2, SwapApiRouterTxResponseV2, SwapApiRoutesRequestV2 } from "./types";
7
-
8
- const QUOTE_API = "/api/v2/quote";
9
- const BUILD_TRANSACTION_API = "/api/v2/buildTransaction";
10
-
11
- const createApiConfig = (stage: TomoStage) => {
12
- const routerApiUrl = stageConfig[stage].routerApiUrl;
13
- const marketApiUrl = stageConfig[stage].marketApiUrl;
14
-
15
- return {
16
- routeApi: axios.create({
17
- baseURL: routerApiUrl,
18
- headers: {
19
- "X-App-Version": "20250427",
20
- },
21
- }),
22
- marketApi: axios.create({
23
- baseURL: marketApiUrl,
24
- }),
25
- };
26
- };
27
-
28
- export const reinitializeApi = (stage: TomoStage, apiConfig: Config | null) => {
29
- const { routeApi, marketApi } = createApiConfig(stage);
30
-
31
- if (!apiConfig) {
32
- throw new Error("Config was not provided");
33
- }
34
-
35
- [routeApi, marketApi].forEach((api) => {
36
- api.interceptors.request.use(
37
- (config) => {
38
- const params = {
39
- method: config.method?.toLocaleUpperCase() || "",
40
- url: config.url || "",
41
- data: config.data,
42
- apiKey: apiConfig.API_KEY,
43
- apiSecret: apiConfig.API_SECRET,
44
- salt: apiConfig.SALT,
45
- // debug: true,
46
- };
47
- const { signature, timestamp } = utils.signature.generateSignature(params);
48
-
49
- Object.assign(config.headers ?? {}, {
50
- "client-id": apiConfig.CLIENT_ID,
51
- "X-APP-Key": apiConfig.API_KEY,
52
- "X-Signature": signature,
53
- "X-Timestamp": timestamp,
54
- });
55
- return config;
56
- },
57
- (error) => {
58
- if (error?.response?.status === 401) {
59
- return Promise.reject(error);
60
- }
61
- },
62
- );
63
- });
64
-
65
- return {
66
- routeApi,
67
- marketApi,
68
- };
69
- };
70
-
71
- export const reinitializeApiMethods = (apiConfig: ApiConfig) => {
72
- const { routeApi, marketApi } = apiConfig;
73
- if (!marketApi || !routeApi) {
74
- throw new Error("API instances are not initialized");
75
- }
76
-
77
- const getTokenInfo = async (queryParameters: {
78
- content: string;
79
- chainIndex?: number;
80
- }): Promise<{
81
- data: IRawApiToken[];
82
- }> => {
83
- const res = await marketApi.get(`/v1/market/token/search`, {
84
- params: queryParameters,
85
- });
86
- return res.data;
87
- };
88
-
89
- const getSwapRoutesV2 = async (params: SwapApiRoutesRequestV2): Promise<TransactionQuoteResult[]> => {
90
- const res = await routeApi.post(QUOTE_API, params);
91
- const data = res?.data?.result?.data;
92
- if (!data) {
93
- const e = new Error("No route found");
94
- e.cause = res?.data;
95
- throw e;
96
- }
97
- return data;
98
- };
99
-
100
- const getSwapRoutesTxV2 = async (params: SwapApiRouterTxRequestV2): Promise<SwapApiRouterTxResponseV2> => {
101
- const res = await routeApi.post(BUILD_TRANSACTION_API, params);
102
- const data = res?.data?.result;
103
- if (data?.transactions[0]?.gasInfo) {
104
- return res.data.result;
105
- } else {
106
- throw new Error("Transaction failed");
107
- }
108
- };
109
-
110
- return {
111
- getTokenInfo,
112
- getSwapRoutesV2,
113
- getSwapRoutesTxV2,
114
- };
115
- };
package/src/api/types.ts DELETED
@@ -1,196 +0,0 @@
1
- import { reinitializeApiMethods } from ".";
2
-
3
- export enum SwapV2DexName {
4
- OKX_SWAP = "OKXSwap",
5
- OKX0 = "OKXCross0",
6
- OKX1 = "OKXCross1",
7
- OKX2 = "OKXCross2",
8
- RANGO_BASIC = "RangoBasic",
9
- RANGO_MAIN = "RangoMain",
10
- JUPITER = "Jupiter",
11
- ARRAKIS_BRIDGE = "ArrakisBridge",
12
- SUN = "Sun",
13
- TOMO = "Tomo",
14
- KODIAK = "Kodiak",
15
- STON = "Ston",
16
- ONE_INCH = "1Inch",
17
- NAVI = "Navi",
18
- DOGE_OS = "DogeOS",
19
- }
20
-
21
- export interface SwapApiRoutesRequestV2 {
22
- amount: string;
23
- dexs: SwapV2DexName[]; //OKXSwap
24
- dexsExclude: boolean;
25
- fromToken: {
26
- address: string;
27
- chainID: string;
28
- decimals: number;
29
- symbol: string;
30
- };
31
- recipient: string;
32
- sender: string;
33
- slippage: number;
34
- toToken: {
35
- address: string;
36
- chainID: string;
37
- decimals: number;
38
- symbol: string;
39
- };
40
- trade_id?: string;
41
- quote_track_id?: string;
42
- user_id?: number;
43
- }
44
-
45
- export type SwapApiRouterTxRequestV2 = {
46
- extendedData:
47
- | {
48
- permit2: {
49
- permit2InputEncode: string;
50
- permitSingle: {
51
- details: {
52
- amount: string;
53
- expiration: number;
54
- nonce: number;
55
- token: string;
56
- };
57
- sigDeadline: number;
58
- spender: string;
59
- };
60
- signature: string;
61
- };
62
- }
63
- | undefined
64
- | null;
65
- quoteID: string;
66
- trade_id?: string;
67
- user_id?: number;
68
- };
69
-
70
- export enum SwapRouterTxEVMType {
71
- APPROVE = "approve",
72
- SWAP = "swap",
73
- EIP712 = "EIP712",
74
- }
75
-
76
- // export type CreateTxMethodParamsV2 = {
77
- // fromToken: IToken;
78
- // toToken: IToken;
79
- // fromAmount: string;
80
- // fromAddress: string;
81
- // toAddress: string;
82
- // slippage?: number;
83
- // routeInfo: DexRouteInfoV2;
84
- // feeMode: FeeMode;
85
- // referrerInfo: {
86
- // referrerFee: number;
87
- // referrerAddress: string;
88
- // }[];
89
- // gasLimit?: string;
90
- // gasPrice?: string;
91
- // evmPermit: TypeEVMPermit | undefined;
92
- // trackInfo?: TrackInfo;
93
- // userInfo?: UserInfo;
94
- // };
95
-
96
- export type SwapRouterTxEVMResult = {
97
- type: SwapRouterTxEVMType;
98
- chainId: number;
99
- data: string;
100
- value: string;
101
- from: string;
102
- to: string;
103
- nonce: number;
104
- gasInfo: {
105
- gasLimit: string;
106
- baseFee: string;
107
- priorityFee: {
108
- low: string;
109
- medium: string;
110
- high: string;
111
- };
112
- };
113
- extended: {
114
- requestID: string;
115
- };
116
- // params?: CreateTxMethodParamsV2;
117
- };
118
-
119
- export type SwapRouterTxSOLResult = {
120
- type: SwapRouterTxEVMType.SWAP;
121
- chainId: number;
122
- data: string;
123
- serializedData: string;
124
- blockHash: string;
125
- gasInfo: {
126
- gasLimit: string;
127
- baseFee: string;
128
- priorityFee: {
129
- low: string;
130
- medium: string;
131
- high: string;
132
- };
133
- };
134
- // params?: CreateTxMethodParamsV2;
135
- };
136
-
137
- export type SwapRouterTxTronResult = {
138
- type: SwapRouterTxEVMType;
139
- chainId: number;
140
- data: string;
141
- value: string;
142
- from: string;
143
- to: string;
144
- rawData: {
145
- visible: boolean;
146
- txID: string;
147
- raw_data: any;
148
- raw_data_hex: string;
149
- };
150
- gasInfo: {
151
- gasLimit: string;
152
- baseFee: string;
153
- };
154
- // params?: CreateTxMethodParamsV2;
155
- };
156
-
157
- export type SwapApiRouterTxResponseV2 = {
158
- transactions: (SwapRouterTxEVMResult | SwapRouterTxSOLResult | SwapRouterTxTronResult)[];
159
- };
160
-
161
- export interface IRawApiToken {
162
- createdTime: string;
163
- updatedTime: string;
164
- id: number;
165
- name: string;
166
- displayName: string;
167
- symbol: string;
168
- imageUrl?: string;
169
- decimals: number;
170
- chain: string;
171
- isNative: boolean;
172
- priceUsd: string;
173
- realPrice?: string;
174
- address: string;
175
- marketCapUsd?: string;
176
- risk: string;
177
- riskLevel?: number;
178
-
179
- isTomoji: boolean;
180
- priceChangeH24: number;
181
- change24h?: number;
182
- volumeH24: string;
183
- fdvUsd: string;
184
- totalSupply: string;
185
- websiteUrl?: string;
186
- twitterUrl?: string;
187
- isPoolBaseToken: boolean;
188
- supportRango: boolean;
189
- groupId: string;
190
- liquidityUsd?: string;
191
- poolAddress?: string;
192
- coingeckoCoinId?: string;
193
- forceSafe?: boolean;
194
- }
195
-
196
- export type ApiMethods = ReturnType<typeof reinitializeApiMethods>;