├── .github └── workflows │ └── publish.yaml ├── .gitignore ├── .prettierignore ├── .prettierrc.json ├── LICENSE ├── README.md ├── assets ├── img.png └── logo.svg ├── examples ├── storage.ts └── swap.ts ├── package-lock.json ├── package.json ├── src ├── api │ ├── .gitignore │ ├── .npmignore │ ├── .openapi-generator-ignore │ ├── .openapi-generator │ │ ├── FILES │ │ └── VERSION │ ├── api.ts │ ├── base.ts │ ├── common.ts │ ├── configuration.ts │ ├── git_push.sh │ └── index.ts ├── index.ts └── transactions.ts └── tsconfig.json /.github/workflows/publish.yaml: -------------------------------------------------------------------------------- 1 | name: Publish Package to npmjs 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | build: 8 | runs-on: ubuntu-latest 9 | permissions: 10 | contents: read 11 | id-token: write 12 | steps: 13 | - uses: actions/checkout@v4 14 | - uses: actions/setup-node@v4 15 | with: 16 | node-version: '20.x' 17 | registry-url: 'https://registry.npmjs.org' 18 | - run: npm ci 19 | - run: npm run prepublish 20 | - run: npm publish --provenance --access public 21 | env: 22 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/*.js 2 | node_modules 3 | typings 4 | dist 5 | 6 | /.idea/ 7 | /dist/ 8 | /node_modules/ 9 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | coverage -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "all", 4 | "singleQuote": true, 5 | "bracketSpacing": true, 6 | "tabWidth": 2, 7 | "printWidth": 100 8 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 swap.coffee 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | swap.coffee logo 3 |

4 | 5 |

SDK for swap.coffee DEX aggregator

6 | 7 |

8 | npm 9 | License 10 | documentation 11 |

12 | 13 | ## Installation 14 | 15 | ```bash 16 | npm install @swap-coffee/sdk 17 | ``` 18 | 19 | Documentation can be found [here](https://docs.swap.coffee). 20 | 21 | 22 | ## Basic usage 23 | 24 | Swapping assets using our SDK and [TonConnect SDK](https://www.npmjs.com/package/@tonconnect/sdk) 25 | 26 | ```typescript 27 | import { waitForRouteResults } from './transactions'; 28 | 29 | const connector = await setupTonConnect(); 30 | const routingApi = new RoutingApi(); 31 | 32 | const assetIn: ApiTokenAddress = { 33 | blockchain: 'ton', 34 | address: 'native', // stands for TON 35 | }; 36 | const assetOut: ApiTokenAddress = { 37 | blockchain: 'ton', 38 | address: 'EQCl0S4xvoeGeFGijTzicSA8j6GiiugmJW5zxQbZTUntre-1', // CES 39 | }; 40 | 41 | const input_amount = 5; // 5 TON 42 | 43 | const route = await routingApi.buildRoute({ 44 | input_token: assetIn, 45 | output_token: assetOut, 46 | output_amount: 200, // desired amount of output token 47 | }); 48 | 49 | const transactions = await routingApi.buildTransactionsV2({ 50 | sender_address: connector.account?.address!!, 51 | slippage: 0.1, 52 | paths: route.data.paths, // note: use route.data here 53 | }); 54 | 55 | 56 | let messages = []; 57 | 58 | for (const transaction of transactions.data.transactions) { 59 | messages.push({ 60 | address: transaction.address, 61 | amount: transaction.value, 62 | payload: transaction.cell, 63 | }); 64 | } 65 | 66 | await connector.sendTransaction({ 67 | validUntil: Date.now() + 5 * 60 * 1000, 68 | messages: messages, 69 | }); 70 | 71 | const results = await waitForRouteResults(transactions.data.route_id, routingApi); 72 | ``` 73 | And here is our transaction: 74 | 75 | ![img.png](assets/img.png) 76 | 77 | Full example code can be found [here](examples/swap.ts) 78 | 79 | ## License 80 | 81 | swap.coffee SDK is [MIT licensed](LICENSE). 82 | 83 | ## Copyright 84 | 85 | swap.coffee © 2024 -------------------------------------------------------------------------------- /assets/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swapcoffee/sdk/71aae77ca0bb98410eafcf13b192ddf0332b62c9/assets/img.png -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /examples/storage.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs/promises'; 3 | import {IStorage} from "@tonconnect/sdk"; 4 | 5 | export interface Storage { 6 | /** 7 | * Saves the `value` to the storage. Value can be accessed later by the `key`. Implementation may use backend as a storage due to the fact that the function returns a promise. 8 | * @param key key to access to the value later. 9 | * @param value value to save. 10 | */ 11 | setItem(key: string, value: string): Promise; 12 | /** 13 | * Reads the `value` from the storage. Implementation may use backend as a storage due to the fact that the function returns a promise. 14 | * @param key key to access the value. 15 | */ 16 | getItem(key: string): Promise; 17 | /** 18 | * Removes the `value` from the storage. Implementation may use backend as a storage due to the fact that the function returns a promise. 19 | * @param key key to access the value. 20 | */ 21 | removeItem(key: string): Promise; 22 | } 23 | 24 | type StorageObject = { 25 | [k: string]: string; 26 | }; 27 | 28 | export class FSStorage implements Storage { 29 | #path: string; 30 | 31 | constructor(path: string) { 32 | this.#path = path; 33 | } 34 | 35 | async #readObject(): Promise { 36 | try { 37 | return JSON.parse((await fs.readFile(this.#path)).toString('utf-8')); 38 | } catch (e) { 39 | return {}; 40 | } 41 | } 42 | 43 | async #writeObject(obj: StorageObject): Promise { 44 | await fs.mkdir(path.dirname(this.#path), { recursive: true }); 45 | await fs.writeFile(this.#path, JSON.stringify(obj)); 46 | } 47 | 48 | async setItem(key: string, value: string): Promise { 49 | const obj = await this.#readObject(); 50 | obj[key] = value; 51 | await this.#writeObject(obj); 52 | } 53 | 54 | async getItem(key: string): Promise { 55 | const obj = await this.#readObject(); 56 | return obj[key] ?? null; 57 | } 58 | 59 | async removeItem(key: string): Promise { 60 | const obj = await this.#readObject(); 61 | delete obj[key]; 62 | await this.#writeObject(obj); 63 | } 64 | } 65 | 66 | export class TonConnectStorage implements IStorage { 67 | #inner: Storage; 68 | 69 | constructor(inner: Storage) { 70 | this.#inner = inner; 71 | } 72 | 73 | async setItem(key: string, value: string): Promise { 74 | return await this.#inner.setItem(key, value); 75 | } 76 | async getItem(key: string): Promise { 77 | return await this.#inner.getItem(key); 78 | } 79 | async removeItem(key: string): Promise { 80 | return await this.#inner.removeItem(key); 81 | } 82 | } -------------------------------------------------------------------------------- /examples/swap.ts: -------------------------------------------------------------------------------- 1 | import { FSStorage, TonConnectStorage } from './storage'; 2 | import TonConnect, { WalletInfo, WalletInfoRemote } from '@tonconnect/sdk'; 3 | import { ApiTokenAddress, RoutingApi, waitForRouteResults } from '../src'; 4 | 5 | function isRemote(walletInfo: WalletInfo): walletInfo is WalletInfoRemote { 6 | return 'universalLink' in walletInfo && 'bridgeUrl' in walletInfo; 7 | } 8 | 9 | export async function setupTonConnect(): Promise { 10 | const connector = new TonConnect({ 11 | storage: new TonConnectStorage(new FSStorage('tonconnect.json')), 12 | manifestUrl: 'https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json', 13 | }); 14 | 15 | const wallets = (await connector.getWallets()).filter(isRemote); 16 | 17 | const wallet = wallets.find(wallet => wallet.name === 'Tonkeeper') as WalletInfoRemote; 18 | 19 | const url = connector.connect({ 20 | universalLink: wallet.universalLink, 21 | bridgeUrl: wallet.bridgeUrl, 22 | }) as string; 23 | 24 | 25 | console.log(url); 26 | 27 | return new Promise((resolve, reject) => { 28 | connector.onStatusChange((w) => { 29 | if (w) { 30 | resolve(connector); 31 | } else { 32 | reject('Wallet is not connected'); 33 | } 34 | }, reject); 35 | }); 36 | } 37 | 38 | 39 | export async function swapAssets() { 40 | const connector = await setupTonConnect(); 41 | const routingApi = new RoutingApi(); 42 | 43 | const assetIn: ApiTokenAddress = { 44 | blockchain: 'ton', 45 | address: 'native', // stands for TON 46 | }; 47 | const assetOut: ApiTokenAddress = { 48 | blockchain: 'ton', 49 | address: 'EQCl0S4xvoeGeFGijTzicSA8j6GiiugmJW5zxQbZTUntre-1', // CES 50 | }; 51 | 52 | const input_amount = 5; // 5 TON 53 | 54 | const route = await routingApi.buildRoute({ 55 | input_token: assetIn, 56 | output_token: assetOut, 57 | output_amount: 200, // desired amount of output token 58 | }); 59 | 60 | console.log(route.data); 61 | 62 | const transactions = await routingApi.buildTransactionsV2({ 63 | sender_address: connector.account?.address!!, 64 | slippage: 0.1, 65 | paths: route.data.paths, // note: use route.data here 66 | }); 67 | 68 | 69 | let messages = []; 70 | 71 | for (const transaction of transactions.data.transactions) { 72 | messages.push({ 73 | address: transaction.address, 74 | amount: transaction.value, 75 | payload: transaction.cell, 76 | }); 77 | } 78 | 79 | await connector.sendTransaction({ 80 | validUntil: Date.now() + 5 * 60 * 1000, 81 | messages: messages, 82 | }); 83 | 84 | const results = await waitForRouteResults(transactions.data.route_id, routingApi); 85 | 86 | console.log(results); // array of transaction results 87 | } 88 | 89 | swapAssets(); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@swapcoffee/sdk", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@swapcoffee/sdk", 9 | "version": "1.0.0", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@tsconfig/node18": "^18.2.1", 13 | "@types/node": "^20.5.9", 14 | "axios": "^1.5.0", 15 | "prettier": "^3.0.3", 16 | "ton-crypto": "^3.2.0", 17 | "ts-node": "^10.9.1", 18 | "typescript": "^5.2.2" 19 | }, 20 | "peerDependencies": { 21 | "@ton/core": ">=0.52.0", 22 | "@tonconnect/sdk": ">=2.1.2", 23 | "axios": ">=1.5.0" 24 | } 25 | }, 26 | "node_modules/@cspotcode/source-map-support": { 27 | "version": "0.8.1", 28 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", 29 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", 30 | "dev": true, 31 | "dependencies": { 32 | "@jridgewell/trace-mapping": "0.3.9" 33 | }, 34 | "engines": { 35 | "node": ">=12" 36 | } 37 | }, 38 | "node_modules/@jridgewell/resolve-uri": { 39 | "version": "3.1.2", 40 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 41 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 42 | "dev": true, 43 | "engines": { 44 | "node": ">=6.0.0" 45 | } 46 | }, 47 | "node_modules/@jridgewell/sourcemap-codec": { 48 | "version": "1.4.15", 49 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 50 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 51 | "dev": true 52 | }, 53 | "node_modules/@jridgewell/trace-mapping": { 54 | "version": "0.3.9", 55 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", 56 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", 57 | "dev": true, 58 | "dependencies": { 59 | "@jridgewell/resolve-uri": "^3.0.3", 60 | "@jridgewell/sourcemap-codec": "^1.4.10" 61 | } 62 | }, 63 | "node_modules/@ton/core": { 64 | "version": "0.56.3", 65 | "resolved": "https://registry.npmjs.org/@ton/core/-/core-0.56.3.tgz", 66 | "integrity": "sha512-HVkalfqw8zqLLPehtq0CNhu5KjVzc7IrbDwDHPjGoOSXmnqSobiWj8a5F+YuWnZnEbQKtrnMGNOOjVw4LG37rg==", 67 | "peer": true, 68 | "dependencies": { 69 | "symbol.inspect": "1.0.1" 70 | }, 71 | "peerDependencies": { 72 | "@ton/crypto": ">=3.2.0" 73 | } 74 | }, 75 | "node_modules/@ton/crypto": { 76 | "version": "3.2.0", 77 | "resolved": "https://registry.npmjs.org/@ton/crypto/-/crypto-3.2.0.tgz", 78 | "integrity": "sha512-50RkwReEuV2FkxSZ8ht/x9+n0ZGtwRKGsJ0ay4I/HFhkYVG/awIIBQeH0W4j8d5lADdO5h01UtX8PJ8AjiejjA==", 79 | "peer": true, 80 | "dependencies": { 81 | "@ton/crypto-primitives": "2.0.0", 82 | "jssha": "3.2.0", 83 | "tweetnacl": "1.0.3" 84 | } 85 | }, 86 | "node_modules/@ton/crypto-primitives": { 87 | "version": "2.0.0", 88 | "resolved": "https://registry.npmjs.org/@ton/crypto-primitives/-/crypto-primitives-2.0.0.tgz", 89 | "integrity": "sha512-wttiNClmGbI6Dfy/8oyNnsIV0b/qYkCJz4Gn4eP62lJZzMtVQ94Ko7nikDX1EfYHkLI1xpOitWpW+8ZuG6XtDg==", 90 | "peer": true, 91 | "dependencies": { 92 | "jssha": "3.2.0" 93 | } 94 | }, 95 | "node_modules/@tonconnect/isomorphic-eventsource": { 96 | "version": "0.0.2", 97 | "resolved": "https://registry.npmjs.org/@tonconnect/isomorphic-eventsource/-/isomorphic-eventsource-0.0.2.tgz", 98 | "integrity": "sha512-B4UoIjPi0QkvIzZH5fV3BQLWrqSYABdrzZQSI9sJA9aA+iC0ohOzFwVVGXanlxeDAy1bcvPbb29f6sVUk0UnnQ==", 99 | "peer": true, 100 | "dependencies": { 101 | "eventsource": "^2.0.2" 102 | } 103 | }, 104 | "node_modules/@tonconnect/isomorphic-fetch": { 105 | "version": "0.0.3", 106 | "resolved": "https://registry.npmjs.org/@tonconnect/isomorphic-fetch/-/isomorphic-fetch-0.0.3.tgz", 107 | "integrity": "sha512-jIg5nTrDwnite4fXao3dD83eCpTvInTjZon/rZZrIftIegh4XxyVb5G2mpMqXrVGk1e8SVXm3Kj5OtfMplQs0w==", 108 | "peer": true, 109 | "dependencies": { 110 | "node-fetch": "^2.6.9" 111 | } 112 | }, 113 | "node_modules/@tonconnect/protocol": { 114 | "version": "2.2.6", 115 | "resolved": "https://registry.npmjs.org/@tonconnect/protocol/-/protocol-2.2.6.tgz", 116 | "integrity": "sha512-kyoDz5EqgsycYP+A+JbVsAUYHNT059BCrK+m0pqxykMODwpziuSAXfwAZmHcg8v7NB9VKYbdFY55xKeXOuEd0w==", 117 | "peer": true, 118 | "dependencies": { 119 | "tweetnacl": "^1.0.3", 120 | "tweetnacl-util": "^0.15.1" 121 | } 122 | }, 123 | "node_modules/@tonconnect/sdk": { 124 | "version": "3.0.3", 125 | "resolved": "https://registry.npmjs.org/@tonconnect/sdk/-/sdk-3.0.3.tgz", 126 | "integrity": "sha512-ElVre1DPixzQLgLtQIa8Wu5xS8nozlgblZTJhFFPrk82M2rZ+sawyF+LAVwt9wZRN7+htWnJrNz0+bBr4b3geA==", 127 | "peer": true, 128 | "dependencies": { 129 | "@tonconnect/isomorphic-eventsource": "^0.0.2", 130 | "@tonconnect/isomorphic-fetch": "^0.0.3", 131 | "@tonconnect/protocol": "^2.2.6" 132 | } 133 | }, 134 | "node_modules/@tsconfig/node10": { 135 | "version": "1.0.11", 136 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", 137 | "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", 138 | "dev": true 139 | }, 140 | "node_modules/@tsconfig/node12": { 141 | "version": "1.0.11", 142 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", 143 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", 144 | "dev": true 145 | }, 146 | "node_modules/@tsconfig/node14": { 147 | "version": "1.0.3", 148 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", 149 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", 150 | "dev": true 151 | }, 152 | "node_modules/@tsconfig/node16": { 153 | "version": "1.0.4", 154 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", 155 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", 156 | "dev": true 157 | }, 158 | "node_modules/@tsconfig/node18": { 159 | "version": "18.2.4", 160 | "resolved": "https://registry.npmjs.org/@tsconfig/node18/-/node18-18.2.4.tgz", 161 | "integrity": "sha512-5xxU8vVs9/FNcvm3gE07fPbn9tl6tqGGWA9tSlwsUEkBxtRnTsNmwrV8gasZ9F/EobaSv9+nu8AxUKccw77JpQ==", 162 | "dev": true 163 | }, 164 | "node_modules/@types/node": { 165 | "version": "20.14.1", 166 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.1.tgz", 167 | "integrity": "sha512-T2MzSGEu+ysB/FkWfqmhV3PLyQlowdptmmgD20C6QxsS8Fmv5SjpZ1ayXaEC0S21/h5UJ9iA6W/5vSNU5l00OA==", 168 | "dev": true, 169 | "dependencies": { 170 | "undici-types": "~5.26.4" 171 | } 172 | }, 173 | "node_modules/acorn": { 174 | "version": "8.11.3", 175 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 176 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 177 | "dev": true, 178 | "bin": { 179 | "acorn": "bin/acorn" 180 | }, 181 | "engines": { 182 | "node": ">=0.4.0" 183 | } 184 | }, 185 | "node_modules/acorn-walk": { 186 | "version": "8.3.2", 187 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", 188 | "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", 189 | "dev": true, 190 | "engines": { 191 | "node": ">=0.4.0" 192 | } 193 | }, 194 | "node_modules/arg": { 195 | "version": "4.1.3", 196 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", 197 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", 198 | "dev": true 199 | }, 200 | "node_modules/asynckit": { 201 | "version": "0.4.0", 202 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 203 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 204 | "dev": true 205 | }, 206 | "node_modules/axios": { 207 | "version": "1.7.2", 208 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", 209 | "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", 210 | "dev": true, 211 | "dependencies": { 212 | "follow-redirects": "^1.15.6", 213 | "form-data": "^4.0.0", 214 | "proxy-from-env": "^1.1.0" 215 | } 216 | }, 217 | "node_modules/combined-stream": { 218 | "version": "1.0.8", 219 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 220 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 221 | "dev": true, 222 | "dependencies": { 223 | "delayed-stream": "~1.0.0" 224 | }, 225 | "engines": { 226 | "node": ">= 0.8" 227 | } 228 | }, 229 | "node_modules/create-require": { 230 | "version": "1.1.1", 231 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", 232 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", 233 | "dev": true 234 | }, 235 | "node_modules/delayed-stream": { 236 | "version": "1.0.0", 237 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 238 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 239 | "dev": true, 240 | "engines": { 241 | "node": ">=0.4.0" 242 | } 243 | }, 244 | "node_modules/diff": { 245 | "version": "4.0.2", 246 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", 247 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", 248 | "dev": true, 249 | "engines": { 250 | "node": ">=0.3.1" 251 | } 252 | }, 253 | "node_modules/eventsource": { 254 | "version": "2.0.2", 255 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz", 256 | "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==", 257 | "peer": true, 258 | "engines": { 259 | "node": ">=12.0.0" 260 | } 261 | }, 262 | "node_modules/follow-redirects": { 263 | "version": "1.15.6", 264 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", 265 | "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", 266 | "dev": true, 267 | "funding": [ 268 | { 269 | "type": "individual", 270 | "url": "https://github.com/sponsors/RubenVerborgh" 271 | } 272 | ], 273 | "engines": { 274 | "node": ">=4.0" 275 | }, 276 | "peerDependenciesMeta": { 277 | "debug": { 278 | "optional": true 279 | } 280 | } 281 | }, 282 | "node_modules/form-data": { 283 | "version": "4.0.0", 284 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 285 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 286 | "dev": true, 287 | "dependencies": { 288 | "asynckit": "^0.4.0", 289 | "combined-stream": "^1.0.8", 290 | "mime-types": "^2.1.12" 291 | }, 292 | "engines": { 293 | "node": ">= 6" 294 | } 295 | }, 296 | "node_modules/jssha": { 297 | "version": "3.2.0", 298 | "resolved": "https://registry.npmjs.org/jssha/-/jssha-3.2.0.tgz", 299 | "integrity": "sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==", 300 | "engines": { 301 | "node": "*" 302 | } 303 | }, 304 | "node_modules/make-error": { 305 | "version": "1.3.6", 306 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", 307 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", 308 | "dev": true 309 | }, 310 | "node_modules/mime-db": { 311 | "version": "1.52.0", 312 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 313 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 314 | "dev": true, 315 | "engines": { 316 | "node": ">= 0.6" 317 | } 318 | }, 319 | "node_modules/mime-types": { 320 | "version": "2.1.35", 321 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 322 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 323 | "dev": true, 324 | "dependencies": { 325 | "mime-db": "1.52.0" 326 | }, 327 | "engines": { 328 | "node": ">= 0.6" 329 | } 330 | }, 331 | "node_modules/node-fetch": { 332 | "version": "2.7.0", 333 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", 334 | "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", 335 | "peer": true, 336 | "dependencies": { 337 | "whatwg-url": "^5.0.0" 338 | }, 339 | "engines": { 340 | "node": "4.x || >=6.0.0" 341 | }, 342 | "peerDependencies": { 343 | "encoding": "^0.1.0" 344 | }, 345 | "peerDependenciesMeta": { 346 | "encoding": { 347 | "optional": true 348 | } 349 | } 350 | }, 351 | "node_modules/prettier": { 352 | "version": "3.3.0", 353 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", 354 | "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", 355 | "dev": true, 356 | "bin": { 357 | "prettier": "bin/prettier.cjs" 358 | }, 359 | "engines": { 360 | "node": ">=14" 361 | }, 362 | "funding": { 363 | "url": "https://github.com/prettier/prettier?sponsor=1" 364 | } 365 | }, 366 | "node_modules/proxy-from-env": { 367 | "version": "1.1.0", 368 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 369 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 370 | "dev": true 371 | }, 372 | "node_modules/symbol.inspect": { 373 | "version": "1.0.1", 374 | "resolved": "https://registry.npmjs.org/symbol.inspect/-/symbol.inspect-1.0.1.tgz", 375 | "integrity": "sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==", 376 | "peer": true 377 | }, 378 | "node_modules/ton-crypto": { 379 | "version": "3.2.0", 380 | "resolved": "https://registry.npmjs.org/ton-crypto/-/ton-crypto-3.2.0.tgz", 381 | "integrity": "sha512-fltdBNQ45gARMuGMEOjPZWPJ5eSql8p3CA0Dj7tPv5lhU5ziT8SxXLAzDraR9HJ8YpjBHLVvYyhMLRiEwxgtMQ==", 382 | "dev": true, 383 | "dependencies": { 384 | "jssha": "3.2.0", 385 | "ton-crypto-primitives": "2.0.0", 386 | "tweetnacl": "1.0.3" 387 | } 388 | }, 389 | "node_modules/ton-crypto-primitives": { 390 | "version": "2.0.0", 391 | "resolved": "https://registry.npmjs.org/ton-crypto-primitives/-/ton-crypto-primitives-2.0.0.tgz", 392 | "integrity": "sha512-K+qKjpS0h9sPW6oExcpxnzuQ7nEgHEiDKwIqE/jWD25o8iFGe3FWj1gKxFNbKE9wwYKc5IV8FwrU+raF0KO5nQ==", 393 | "dev": true, 394 | "dependencies": { 395 | "jssha": "3.2.0" 396 | } 397 | }, 398 | "node_modules/tr46": { 399 | "version": "0.0.3", 400 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", 401 | "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", 402 | "peer": true 403 | }, 404 | "node_modules/ts-node": { 405 | "version": "10.9.2", 406 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", 407 | "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", 408 | "dev": true, 409 | "dependencies": { 410 | "@cspotcode/source-map-support": "^0.8.0", 411 | "@tsconfig/node10": "^1.0.7", 412 | "@tsconfig/node12": "^1.0.7", 413 | "@tsconfig/node14": "^1.0.0", 414 | "@tsconfig/node16": "^1.0.2", 415 | "acorn": "^8.4.1", 416 | "acorn-walk": "^8.1.1", 417 | "arg": "^4.1.0", 418 | "create-require": "^1.1.0", 419 | "diff": "^4.0.1", 420 | "make-error": "^1.1.1", 421 | "v8-compile-cache-lib": "^3.0.1", 422 | "yn": "3.1.1" 423 | }, 424 | "bin": { 425 | "ts-node": "dist/bin.js", 426 | "ts-node-cwd": "dist/bin-cwd.js", 427 | "ts-node-esm": "dist/bin-esm.js", 428 | "ts-node-script": "dist/bin-script.js", 429 | "ts-node-transpile-only": "dist/bin-transpile.js", 430 | "ts-script": "dist/bin-script-deprecated.js" 431 | }, 432 | "peerDependencies": { 433 | "@swc/core": ">=1.2.50", 434 | "@swc/wasm": ">=1.2.50", 435 | "@types/node": "*", 436 | "typescript": ">=2.7" 437 | }, 438 | "peerDependenciesMeta": { 439 | "@swc/core": { 440 | "optional": true 441 | }, 442 | "@swc/wasm": { 443 | "optional": true 444 | } 445 | } 446 | }, 447 | "node_modules/tweetnacl": { 448 | "version": "1.0.3", 449 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz", 450 | "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==" 451 | }, 452 | "node_modules/tweetnacl-util": { 453 | "version": "0.15.1", 454 | "resolved": "https://registry.npmjs.org/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz", 455 | "integrity": "sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==", 456 | "peer": true 457 | }, 458 | "node_modules/typescript": { 459 | "version": "5.4.5", 460 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 461 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 462 | "dev": true, 463 | "bin": { 464 | "tsc": "bin/tsc", 465 | "tsserver": "bin/tsserver" 466 | }, 467 | "engines": { 468 | "node": ">=14.17" 469 | } 470 | }, 471 | "node_modules/undici-types": { 472 | "version": "5.26.5", 473 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 474 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 475 | "dev": true 476 | }, 477 | "node_modules/v8-compile-cache-lib": { 478 | "version": "3.0.1", 479 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", 480 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", 481 | "dev": true 482 | }, 483 | "node_modules/webidl-conversions": { 484 | "version": "3.0.1", 485 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", 486 | "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", 487 | "peer": true 488 | }, 489 | "node_modules/whatwg-url": { 490 | "version": "5.0.0", 491 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", 492 | "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", 493 | "peer": true, 494 | "dependencies": { 495 | "tr46": "~0.0.3", 496 | "webidl-conversions": "^3.0.0" 497 | } 498 | }, 499 | "node_modules/yn": { 500 | "version": "3.1.1", 501 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", 502 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", 503 | "dev": true, 504 | "engines": { 505 | "node": ">=6" 506 | } 507 | } 508 | } 509 | } 510 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@swap-coffee/sdk", 3 | "version": "1.5.4", 4 | "description": "SDK for swap.coffee DEX aggregator", 5 | "license": "MIT", 6 | "homepage": "https://swap.coffee", 7 | "author": { 8 | "name": "CatCoderr" 9 | }, 10 | "files": [ 11 | "dist" 12 | ], 13 | "repository": { 14 | "url": "https://github.com/swapcoffee/sdk" 15 | }, 16 | "main": "dist/index.js", 17 | "types": "dist/index.d.ts", 18 | "keywords": [ 19 | "swapcoffee", 20 | "dedust", 21 | "stonfi", 22 | "ton", 23 | "dex" 24 | ], 25 | "devDependencies": { 26 | "@tsconfig/node18": "^18.2.1", 27 | "@types/node": "^20.5.9", 28 | "axios": "^1.5.0", 29 | "prettier": "^3.0.3", 30 | "ton-crypto": "^3.2.0", 31 | "ts-node": "^10.9.1", 32 | "typescript": "^5.2.2" 33 | }, 34 | "peerDependencies": { 35 | "@ton/core": ">=0.52.0", 36 | "@tonconnect/sdk": ">=2.1.2", 37 | "axios": ">=1.5.0" 38 | }, 39 | "scripts": { 40 | "build": "tsc", 41 | "fmt": "prettier . --write", 42 | "prepublish": "tsc" 43 | } 44 | } -------------------------------------------------------------------------------- /src/api/.gitignore: -------------------------------------------------------------------------------- 1 | wwwroot/*.js 2 | node_modules 3 | typings 4 | dist 5 | -------------------------------------------------------------------------------- /src/api/.npmignore: -------------------------------------------------------------------------------- 1 | # empty npmignore to ensure all required files (e.g., in the dist folder) are published by npm -------------------------------------------------------------------------------- /src/api/.openapi-generator-ignore: -------------------------------------------------------------------------------- 1 | # OpenAPI Generator Ignore 2 | # Generated by openapi-generator https://github.com/openapitools/openapi-generator 3 | 4 | # Use this file to prevent files from being overwritten by the generator. 5 | # The patterns follow closely to .gitignore or .dockerignore. 6 | 7 | # As an example, the C# client generator defines ApiClient.cs. 8 | # You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: 9 | #ApiClient.cs 10 | 11 | # You can match any string of characters against a directory, file or extension with a single asterisk (*): 12 | #foo/*/qux 13 | # The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux 14 | 15 | # You can recursively match patterns against a directory, file or extension with a double asterisk (**): 16 | #foo/**/qux 17 | # This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux 18 | 19 | # You can also negate patterns with an exclamation (!). 20 | # For example, you can ignore all files in a docs folder with the file extension .md: 21 | #docs/*.md 22 | # Then explicitly reverse the ignore rule for a single file: 23 | #!docs/README.md 24 | -------------------------------------------------------------------------------- /src/api/.openapi-generator/FILES: -------------------------------------------------------------------------------- 1 | .gitignore 2 | .npmignore 3 | api.ts 4 | base.ts 5 | common.ts 6 | configuration.ts 7 | git_push.sh 8 | index.ts 9 | -------------------------------------------------------------------------------- /src/api/.openapi-generator/VERSION: -------------------------------------------------------------------------------- 1 | 7.11.0 2 | -------------------------------------------------------------------------------- /src/api/base.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Swap Coffee API 5 | * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | 16 | import type { Configuration } from './configuration'; 17 | // Some imports not used depending on template conditions 18 | // @ts-ignore 19 | import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig } from 'axios'; 20 | import globalAxios from 'axios'; 21 | 22 | export const BASE_PATH = "https://backend.swap.coffee".replace(/\/+$/, ""); 23 | 24 | /** 25 | * 26 | * @export 27 | */ 28 | export const COLLECTION_FORMATS = { 29 | csv: ",", 30 | ssv: " ", 31 | tsv: "\t", 32 | pipes: "|", 33 | }; 34 | 35 | /** 36 | * 37 | * @export 38 | * @interface RequestArgs 39 | */ 40 | export interface RequestArgs { 41 | url: string; 42 | options: RawAxiosRequestConfig; 43 | } 44 | 45 | /** 46 | * 47 | * @export 48 | * @class BaseAPI 49 | */ 50 | export class BaseAPI { 51 | protected configuration: Configuration | undefined; 52 | 53 | constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) { 54 | if (configuration) { 55 | this.configuration = configuration; 56 | this.basePath = configuration.basePath ?? basePath; 57 | } 58 | } 59 | }; 60 | 61 | /** 62 | * 63 | * @export 64 | * @class RequiredError 65 | * @extends {Error} 66 | */ 67 | export class RequiredError extends Error { 68 | constructor(public field: string, msg?: string) { 69 | super(msg); 70 | this.name = "RequiredError" 71 | } 72 | } 73 | 74 | interface ServerMap { 75 | [key: string]: { 76 | url: string, 77 | description: string, 78 | }[]; 79 | } 80 | 81 | /** 82 | * 83 | * @export 84 | */ 85 | export const operationServerMap: ServerMap = { 86 | } 87 | -------------------------------------------------------------------------------- /src/api/common.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Swap Coffee API 5 | * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | 16 | import type { Configuration } from "./configuration"; 17 | import type { RequestArgs } from "./base"; 18 | import type { AxiosInstance, AxiosResponse } from 'axios'; 19 | import { RequiredError } from "./base"; 20 | 21 | /** 22 | * 23 | * @export 24 | */ 25 | export const DUMMY_BASE_URL = 'https://example.com' 26 | 27 | /** 28 | * 29 | * @throws {RequiredError} 30 | * @export 31 | */ 32 | export const assertParamExists = function (functionName: string, paramName: string, paramValue: unknown) { 33 | if (paramValue === null || paramValue === undefined) { 34 | throw new RequiredError(paramName, `Required parameter ${paramName} was null or undefined when calling ${functionName}.`); 35 | } 36 | } 37 | 38 | /** 39 | * 40 | * @export 41 | */ 42 | export const setApiKeyToObject = async function (object: any, keyParamName: string, configuration?: Configuration) { 43 | if (configuration && configuration.apiKey) { 44 | const localVarApiKeyValue = typeof configuration.apiKey === 'function' 45 | ? await configuration.apiKey(keyParamName) 46 | : await configuration.apiKey; 47 | object[keyParamName] = localVarApiKeyValue; 48 | } 49 | } 50 | 51 | /** 52 | * 53 | * @export 54 | */ 55 | export const setBasicAuthToObject = function (object: any, configuration?: Configuration) { 56 | if (configuration && (configuration.username || configuration.password)) { 57 | object["auth"] = { username: configuration.username, password: configuration.password }; 58 | } 59 | } 60 | 61 | /** 62 | * 63 | * @export 64 | */ 65 | export const setBearerAuthToObject = async function (object: any, configuration?: Configuration) { 66 | if (configuration && configuration.accessToken) { 67 | const accessToken = typeof configuration.accessToken === 'function' 68 | ? await configuration.accessToken() 69 | : await configuration.accessToken; 70 | object["Authorization"] = "Bearer " + accessToken; 71 | } 72 | } 73 | 74 | /** 75 | * 76 | * @export 77 | */ 78 | export const setOAuthToObject = async function (object: any, name: string, scopes: string[], configuration?: Configuration) { 79 | if (configuration && configuration.accessToken) { 80 | const localVarAccessTokenValue = typeof configuration.accessToken === 'function' 81 | ? await configuration.accessToken(name, scopes) 82 | : await configuration.accessToken; 83 | object["Authorization"] = "Bearer " + localVarAccessTokenValue; 84 | } 85 | } 86 | 87 | function setFlattenedQueryParams(urlSearchParams: URLSearchParams, parameter: any, key: string = ""): void { 88 | if (parameter == null) return; 89 | if (typeof parameter === "object") { 90 | if (Array.isArray(parameter)) { 91 | (parameter as any[]).forEach(item => setFlattenedQueryParams(urlSearchParams, item, key)); 92 | } 93 | else { 94 | Object.keys(parameter).forEach(currentKey => 95 | setFlattenedQueryParams(urlSearchParams, parameter[currentKey], `${key}${key !== '' ? '.' : ''}${currentKey}`) 96 | ); 97 | } 98 | } 99 | else { 100 | if (urlSearchParams.has(key)) { 101 | urlSearchParams.append(key, parameter); 102 | } 103 | else { 104 | urlSearchParams.set(key, parameter); 105 | } 106 | } 107 | } 108 | 109 | /** 110 | * 111 | * @export 112 | */ 113 | export const setSearchParams = function (url: URL, ...objects: any[]) { 114 | const searchParams = new URLSearchParams(url.search); 115 | setFlattenedQueryParams(searchParams, objects); 116 | url.search = searchParams.toString(); 117 | } 118 | 119 | /** 120 | * 121 | * @export 122 | */ 123 | export const serializeDataIfNeeded = function (value: any, requestOptions: any, configuration?: Configuration) { 124 | const nonString = typeof value !== 'string'; 125 | const needsSerialization = nonString && configuration && configuration.isJsonMime 126 | ? configuration.isJsonMime(requestOptions.headers['Content-Type']) 127 | : nonString; 128 | return needsSerialization 129 | ? JSON.stringify(value !== undefined ? value : {}) 130 | : (value || ""); 131 | } 132 | 133 | /** 134 | * 135 | * @export 136 | */ 137 | export const toPathString = function (url: URL) { 138 | return url.pathname + url.search + url.hash 139 | } 140 | 141 | /** 142 | * 143 | * @export 144 | */ 145 | export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) { 146 | return >(axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => { 147 | const axiosRequestArgs = {...axiosArgs.options, url: (axios.defaults.baseURL ? '' : configuration?.basePath ?? basePath) + axiosArgs.url}; 148 | return axios.request(axiosRequestArgs); 149 | }; 150 | } 151 | -------------------------------------------------------------------------------- /src/api/configuration.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Swap Coffee API 5 | * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | 16 | export interface ConfigurationParameters { 17 | apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); 18 | username?: string; 19 | password?: string; 20 | accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); 21 | basePath?: string; 22 | serverIndex?: number; 23 | baseOptions?: any; 24 | formDataCtor?: new () => any; 25 | } 26 | 27 | export class Configuration { 28 | /** 29 | * parameter for apiKey security 30 | * @param name security name 31 | * @memberof Configuration 32 | */ 33 | apiKey?: string | Promise | ((name: string) => string) | ((name: string) => Promise); 34 | /** 35 | * parameter for basic security 36 | * 37 | * @type {string} 38 | * @memberof Configuration 39 | */ 40 | username?: string; 41 | /** 42 | * parameter for basic security 43 | * 44 | * @type {string} 45 | * @memberof Configuration 46 | */ 47 | password?: string; 48 | /** 49 | * parameter for oauth2 security 50 | * @param name security name 51 | * @param scopes oauth2 scope 52 | * @memberof Configuration 53 | */ 54 | accessToken?: string | Promise | ((name?: string, scopes?: string[]) => string) | ((name?: string, scopes?: string[]) => Promise); 55 | /** 56 | * override base path 57 | * 58 | * @type {string} 59 | * @memberof Configuration 60 | */ 61 | basePath?: string; 62 | /** 63 | * override server index 64 | * 65 | * @type {number} 66 | * @memberof Configuration 67 | */ 68 | serverIndex?: number; 69 | /** 70 | * base options for axios calls 71 | * 72 | * @type {any} 73 | * @memberof Configuration 74 | */ 75 | baseOptions?: any; 76 | /** 77 | * The FormData constructor that will be used to create multipart form data 78 | * requests. You can inject this here so that execution environments that 79 | * do not support the FormData class can still run the generated client. 80 | * 81 | * @type {new () => FormData} 82 | */ 83 | formDataCtor?: new () => any; 84 | 85 | constructor(param: ConfigurationParameters = {}) { 86 | this.apiKey = param.apiKey; 87 | this.username = param.username; 88 | this.password = param.password; 89 | this.accessToken = param.accessToken; 90 | this.basePath = param.basePath; 91 | this.serverIndex = param.serverIndex; 92 | this.baseOptions = { 93 | headers: { 94 | ...param.baseOptions?.headers, 95 | 'User-Agent': "OpenAPI-Generator/typescript-axios" 96 | }, 97 | ...param.baseOptions 98 | }; 99 | this.formDataCtor = param.formDataCtor; 100 | } 101 | 102 | /** 103 | * Check if the given MIME is a JSON MIME. 104 | * JSON MIME examples: 105 | * application/json 106 | * application/json; charset=UTF8 107 | * APPLICATION/JSON 108 | * application/vnd.company+json 109 | * @param mime - MIME (Multipurpose Internet Mail Extensions) 110 | * @return True if the given MIME is JSON, false otherwise. 111 | */ 112 | public isJsonMime(mime: string): boolean { 113 | const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i'); 114 | return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json'); 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/api/git_push.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ 3 | # 4 | # Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" 5 | 6 | git_user_id=$1 7 | git_repo_id=$2 8 | release_note=$3 9 | git_host=$4 10 | 11 | if [ "$git_host" = "" ]; then 12 | git_host="github.com" 13 | echo "[INFO] No command line input provided. Set \$git_host to $git_host" 14 | fi 15 | 16 | if [ "$git_user_id" = "" ]; then 17 | git_user_id="GIT_USER_ID" 18 | echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" 19 | fi 20 | 21 | if [ "$git_repo_id" = "" ]; then 22 | git_repo_id="GIT_REPO_ID" 23 | echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" 24 | fi 25 | 26 | if [ "$release_note" = "" ]; then 27 | release_note="Minor update" 28 | echo "[INFO] No command line input provided. Set \$release_note to $release_note" 29 | fi 30 | 31 | # Initialize the local directory as a Git repository 32 | git init 33 | 34 | # Adds the files in the local repository and stages them for commit. 35 | git add . 36 | 37 | # Commits the tracked changes and prepares them to be pushed to a remote repository. 38 | git commit -m "$release_note" 39 | 40 | # Sets the new remote 41 | git_remote=$(git remote) 42 | if [ "$git_remote" = "" ]; then # git remote not defined 43 | 44 | if [ "$GIT_TOKEN" = "" ]; then 45 | echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." 46 | git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git 47 | else 48 | git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git 49 | fi 50 | 51 | fi 52 | 53 | git pull origin master 54 | 55 | # Pushes (Forces) the changes in the local repository up to the remote repository 56 | echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" 57 | git push origin master 2>&1 | grep -v 'To https' 58 | -------------------------------------------------------------------------------- /src/api/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /** 4 | * Swap Coffee API 5 | * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) 6 | * 7 | * The version of the OpenAPI document: 1.0.0 8 | * 9 | * 10 | * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). 11 | * https://openapi-generator.tech 12 | * Do not edit the class manually. 13 | */ 14 | 15 | 16 | export * from "./api"; 17 | export * from "./configuration"; 18 | 19 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | 4 | export * from "./api"; 5 | export * from "./transactions"; 6 | 7 | -------------------------------------------------------------------------------- /src/transactions.ts: -------------------------------------------------------------------------------- 1 | import { ApiSplitResult, RoutingApi } from './api'; 2 | 3 | 4 | /** 5 | * Wait for transaction result by route id 6 | * 7 | * @param routeId - route id 8 | * @param api - instance of {@link RoutingApi} 9 | * @param period - period of time to wait for result (default 1000 ms) 10 | */ 11 | export async function waitForRouteResults(routeId: number, api: RoutingApi, period: number = 10_000): Promise { 12 | let result = await api.getRouteResult(routeId); 13 | 14 | return new Promise(async (resolve, reject) => { 15 | 16 | while (!allSplitsCompleted(result.data.splits)) { 17 | await new Promise(resolve => setTimeout(resolve, period)); 18 | result = await api.getRouteResult(routeId); 19 | } 20 | 21 | resolve(result.data.splits); 22 | }); 23 | } 24 | 25 | 26 | function allSplitsCompleted(transactions: ApiSplitResult[]): boolean { 27 | return transactions.every(transaction => transaction.status != 'pending' && transaction.status != 'partially_complete'); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@tsconfig/node18/tsconfig.json", 3 | "compilerOptions": { 4 | "declaration": true, 5 | "sourceMap": true, 6 | "outDir": "dist", 7 | "lib": ["DOM", "ES2022"] 8 | }, 9 | "include": ["src"], 10 | "exclude": ["node_modules"] 11 | } --------------------------------------------------------------------------------