@snowmonster_defi/sdk 1.0.3
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/README.md +368 -0
- package/dist/index.d.mts +177 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.js +211 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +180 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +133 -0
- package/dist/react/index.d.ts +133 -0
- package/dist/react/index.js +270 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +242 -0
- package/dist/react/index.mjs.map +1 -0
- package/package.json +103 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
API_ENDPOINTS: () => API_ENDPOINTS,
|
|
24
|
+
AVALANCHE_TOKENS: () => AVALANCHE_TOKENS,
|
|
25
|
+
AvaxRouter: () => AvaxRouter,
|
|
26
|
+
DEX_ROUTER_ADDRESS: () => DEX_ROUTER_ADDRESS,
|
|
27
|
+
getClient: () => getClient
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// src/types.ts
|
|
32
|
+
var AVALANCHE_TOKENS = {
|
|
33
|
+
AVAX: "0x0000000000000000000000000000000000000000",
|
|
34
|
+
WAVAX: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",
|
|
35
|
+
USDC: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
|
|
36
|
+
USDT: "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
|
|
37
|
+
JOE: "0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd",
|
|
38
|
+
PNG: "0x60781C2586D68229fde47564546784ab3fACA982"
|
|
39
|
+
};
|
|
40
|
+
var DEX_ROUTER_ADDRESS = "0xYourDeployedContractAddress";
|
|
41
|
+
var API_ENDPOINTS = {
|
|
42
|
+
mainnet: "https://api.avaxrouter.com",
|
|
43
|
+
testnet: "https://api-testnet.avaxrouter.com",
|
|
44
|
+
local: "http://localhost:3000"
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/client.ts
|
|
48
|
+
var AvaxRouter = class {
|
|
49
|
+
constructor(config = {}) {
|
|
50
|
+
this.apiUrl = config.apiUrl || API_ENDPOINTS.mainnet;
|
|
51
|
+
this.partnerId = config.partnerId;
|
|
52
|
+
this.partnerFeeBps = config.partnerFeeBps;
|
|
53
|
+
this.partnerAddress = config.partnerAddress;
|
|
54
|
+
if (this.partnerFeeBps && this.partnerFeeBps > 50) {
|
|
55
|
+
throw new Error("Partner fee cannot exceed 50 basis points (0.50%)");
|
|
56
|
+
}
|
|
57
|
+
if (this.partnerFeeBps && !this.partnerAddress) {
|
|
58
|
+
throw new Error("Partner address required when partner fee is set");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get the best quote across all DEXes
|
|
63
|
+
*/
|
|
64
|
+
async getBestQuote(params) {
|
|
65
|
+
const queryParams = new URLSearchParams({
|
|
66
|
+
tokenIn: params.tokenIn,
|
|
67
|
+
tokenOut: params.tokenOut,
|
|
68
|
+
amountIn: params.amountIn
|
|
69
|
+
});
|
|
70
|
+
if (this.partnerId) {
|
|
71
|
+
queryParams.append("partnerId", this.partnerId);
|
|
72
|
+
}
|
|
73
|
+
const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
76
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
77
|
+
}
|
|
78
|
+
const data = await response.json();
|
|
79
|
+
return {
|
|
80
|
+
...data,
|
|
81
|
+
amountIn: BigInt(data.amountIn),
|
|
82
|
+
amountOut: BigInt(data.amountOut),
|
|
83
|
+
allQuotes: data.allQuotes.map((q) => ({
|
|
84
|
+
...q,
|
|
85
|
+
amountOut: BigInt(q.amountOut)
|
|
86
|
+
})),
|
|
87
|
+
estimatedGas: data.estimatedGas ? BigInt(data.estimatedGas) : void 0
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get quotes from all DEXes
|
|
92
|
+
*/
|
|
93
|
+
async getAllQuotes(params) {
|
|
94
|
+
const queryParams = new URLSearchParams({
|
|
95
|
+
tokenIn: params.tokenIn,
|
|
96
|
+
tokenOut: params.tokenOut,
|
|
97
|
+
amountIn: params.amountIn,
|
|
98
|
+
allDexes: "true"
|
|
99
|
+
});
|
|
100
|
+
const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);
|
|
101
|
+
if (!response.ok) {
|
|
102
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
103
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
104
|
+
}
|
|
105
|
+
return response.json();
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Prepare a swap transaction (returns unsigned transaction data)
|
|
109
|
+
*/
|
|
110
|
+
async prepareSwap(params) {
|
|
111
|
+
const body = {
|
|
112
|
+
tokenIn: params.tokenIn,
|
|
113
|
+
tokenOut: params.tokenOut,
|
|
114
|
+
amountIn: params.amountIn,
|
|
115
|
+
slippagePercent: params.slippagePercent ?? 0.5,
|
|
116
|
+
recipient: params.recipient
|
|
117
|
+
};
|
|
118
|
+
if (this.partnerAddress && this.partnerFeeBps) {
|
|
119
|
+
body.partner = this.partnerAddress;
|
|
120
|
+
body.partnerFeeBps = this.partnerFeeBps;
|
|
121
|
+
}
|
|
122
|
+
const response = await fetch(`${this.apiUrl}/swap/prepare`, {
|
|
123
|
+
method: "POST",
|
|
124
|
+
headers: { "Content-Type": "application/json" },
|
|
125
|
+
body: JSON.stringify(body)
|
|
126
|
+
});
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
129
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
130
|
+
}
|
|
131
|
+
return response.json();
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Execute a swap (requires signer - use with ethers.js or viem)
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* // With ethers.js
|
|
138
|
+
* const router = new AvaxRouter();
|
|
139
|
+
* const signer = await ethers.getSigner();
|
|
140
|
+
* const result = await router.swap({ tokenIn: 'AVAX', tokenOut: 'USDC', amountIn: '1.0' }, signer);
|
|
141
|
+
*/
|
|
142
|
+
async swap(params, signer) {
|
|
143
|
+
const txData = await this.prepareSwap(params);
|
|
144
|
+
const tx = await signer.sendTransaction({
|
|
145
|
+
to: txData.to,
|
|
146
|
+
data: txData.data,
|
|
147
|
+
value: txData.value
|
|
148
|
+
});
|
|
149
|
+
const receipt = await tx.wait();
|
|
150
|
+
return {
|
|
151
|
+
txHash: receipt.hash,
|
|
152
|
+
amountIn: params.amountIn,
|
|
153
|
+
amountOut: "0",
|
|
154
|
+
// Would need to parse from logs
|
|
155
|
+
dexUsed: "unknown",
|
|
156
|
+
// Would need to parse from logs
|
|
157
|
+
protocolFee: "0"
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get the status of a swap transaction
|
|
162
|
+
*/
|
|
163
|
+
async getSwapStatus(txHash) {
|
|
164
|
+
const response = await fetch(`${this.apiUrl}/swap/status/${txHash}`);
|
|
165
|
+
if (!response.ok) {
|
|
166
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
167
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
168
|
+
}
|
|
169
|
+
const data = await response.json();
|
|
170
|
+
return {
|
|
171
|
+
...data,
|
|
172
|
+
gasUsed: data.gasUsed ? BigInt(data.gasUsed) : void 0
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get list of supported tokens
|
|
177
|
+
*/
|
|
178
|
+
async getSupportedTokens() {
|
|
179
|
+
const response = await fetch(`${this.apiUrl}/tokens`);
|
|
180
|
+
if (!response.ok) {
|
|
181
|
+
throw new Error(`API error: ${response.status}`);
|
|
182
|
+
}
|
|
183
|
+
return response.json();
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Get list of supported DEXes
|
|
187
|
+
*/
|
|
188
|
+
async getSupportedDexes() {
|
|
189
|
+
const response = await fetch(`${this.apiUrl}/dexes`);
|
|
190
|
+
if (!response.ok) {
|
|
191
|
+
throw new Error(`API error: ${response.status}`);
|
|
192
|
+
}
|
|
193
|
+
return response.json();
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
var defaultClient = null;
|
|
197
|
+
function getClient(config) {
|
|
198
|
+
if (!defaultClient || config) {
|
|
199
|
+
defaultClient = new AvaxRouter(config);
|
|
200
|
+
}
|
|
201
|
+
return defaultClient;
|
|
202
|
+
}
|
|
203
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
204
|
+
0 && (module.exports = {
|
|
205
|
+
API_ENDPOINTS,
|
|
206
|
+
AVALANCHE_TOKENS,
|
|
207
|
+
AvaxRouter,
|
|
208
|
+
DEX_ROUTER_ADDRESS,
|
|
209
|
+
getClient
|
|
210
|
+
});
|
|
211
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/types.ts","../src/client.ts"],"sourcesContent":["/**\n * AVAX Router SDK\n * \n * No favorites. No games. Just the best price.\n * \n * @example\n * import { AvaxRouter } from '@avax-router/sdk';\n * \n * const router = new AvaxRouter();\n * const quote = await router.getBestQuote({\n * tokenIn: 'AVAX',\n * tokenOut: 'USDC',\n * amountIn: '1.0',\n * });\n */\n\n// Core client\nexport { AvaxRouter, getClient } from './client';\n\n// Types\nexport type {\n AvaxRouterConfig,\n TokenInfo,\n QuoteParams,\n QuoteResult,\n DexQuote,\n SwapParams,\n SwapResult,\n SwapStatus,\n} from './types';\n\n// Constants\nexport {\n AVALANCHE_TOKENS,\n DEX_ROUTER_ADDRESS,\n API_ENDPOINTS,\n} from './types';\n","/**\n * AVAX Router SDK Types\n */\n\nexport interface AvaxRouterConfig {\n /** API base URL (default: https://api.avaxrouter.com) */\n apiUrl?: string;\n /** Partner ID for fee sharing */\n partnerId?: string;\n /** Partner fee in basis points (max 50 = 0.50%) */\n partnerFeeBps?: number;\n /** Partner address to receive fees */\n partnerAddress?: string;\n}\n\nexport interface TokenInfo {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n logoURI?: string;\n}\n\nexport interface QuoteParams {\n /** Input token address or symbol */\n tokenIn: string;\n /** Output token address or symbol */\n tokenOut: string;\n /** Amount of input tokens (in human-readable format) */\n amountIn: string;\n}\n\nexport interface QuoteResult {\n /** Input token address */\n tokenIn: string;\n /** Output token address */\n tokenOut: string;\n /** Amount in (raw) */\n amountIn: bigint;\n /** Expected amount out (raw) */\n amountOut: bigint;\n /** Amount out formatted for display */\n amountOutFormatted: string;\n /** Best DEX for this route */\n bestDex: string;\n /** All quotes from different DEXes */\n allQuotes: DexQuote[];\n /** Price impact */\n priceImpact?: number;\n /** Route path (for multi-hop) */\n route?: string[];\n /** Protocol fee in basis points */\n protocolFeeBps: number;\n /** Partner fee in basis points (if applicable) */\n partnerFeeBps?: number;\n /** Estimated gas cost */\n estimatedGas?: bigint;\n}\n\nexport interface DexQuote {\n /** DEX name */\n dex: string;\n /** Output amount (raw) */\n amountOut: bigint;\n /** Output amount formatted */\n amountOutFormatted: string;\n /** Whether this quote is the best */\n isBest: boolean;\n}\n\nexport interface SwapParams extends QuoteParams {\n /** Minimum output amount (slippage protection) */\n minAmountOut?: string;\n /** Slippage tolerance in percent (default: 0.5) */\n slippagePercent?: number;\n /** Recipient address (defaults to connected wallet) */\n recipient?: string;\n /** Deadline in seconds (default: 1200 = 20 min) */\n deadline?: number;\n}\n\nexport interface SwapResult {\n /** Transaction hash */\n txHash: string;\n /** Amount of tokens swapped */\n amountIn: string;\n /** Amount of tokens received */\n amountOut: string;\n /** DEX used for the swap */\n dexUsed: string;\n /** Protocol fee paid */\n protocolFee: string;\n /** Partner fee paid (if applicable) */\n partnerFee?: string;\n}\n\nexport interface SwapStatus {\n status: 'pending' | 'confirmed' | 'failed';\n txHash?: string;\n blockNumber?: number;\n gasUsed?: bigint;\n amountIn?: string;\n amountOut?: string;\n error?: string;\n}\n\n// Avalanche token addresses\nexport const AVALANCHE_TOKENS = {\n AVAX: '0x0000000000000000000000000000000000000000',\n WAVAX: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7',\n USDC: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n USDT: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',\n JOE: '0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd',\n PNG: '0x60781C2586D68229fde47564546784ab3fACA982',\n} as const;\n\n// DexRouter contract address on Avalanche\nexport const DEX_ROUTER_ADDRESS = '0xYourDeployedContractAddress' as `0x${string}`;\n\n// API endpoints\nexport const API_ENDPOINTS = {\n mainnet: 'https://api.avaxrouter.com',\n testnet: 'https://api-testnet.avaxrouter.com',\n local: 'http://localhost:3000',\n} as const;","/**\n * AVAX Router SDK Client\n * \n * Main entry point for interacting with AVAX Router\n */\n\nimport {\n AvaxRouterConfig,\n QuoteParams,\n QuoteResult,\n SwapParams,\n SwapResult,\n SwapStatus,\n API_ENDPOINTS,\n} from './types';\n\nexport class AvaxRouter {\n private apiUrl: string;\n private partnerId?: string;\n private partnerFeeBps?: number;\n private partnerAddress?: string;\n\n constructor(config: AvaxRouterConfig = {}) {\n this.apiUrl = config.apiUrl || API_ENDPOINTS.mainnet;\n this.partnerId = config.partnerId;\n this.partnerFeeBps = config.partnerFeeBps;\n this.partnerAddress = config.partnerAddress;\n\n // Validate partner config\n if (this.partnerFeeBps && this.partnerFeeBps > 50) {\n throw new Error('Partner fee cannot exceed 50 basis points (0.50%)');\n }\n if (this.partnerFeeBps && !this.partnerAddress) {\n throw new Error('Partner address required when partner fee is set');\n }\n }\n\n /**\n * Get the best quote across all DEXes\n */\n async getBestQuote(params: QuoteParams): Promise<QuoteResult> {\n const queryParams = new URLSearchParams({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n });\n\n if (this.partnerId) {\n queryParams.append('partnerId', this.partnerId);\n }\n\n const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n const data = await response.json();\n \n return {\n ...data,\n amountIn: BigInt(data.amountIn),\n amountOut: BigInt(data.amountOut),\n allQuotes: data.allQuotes.map((q: any) => ({\n ...q,\n amountOut: BigInt(q.amountOut),\n })),\n estimatedGas: data.estimatedGas ? BigInt(data.estimatedGas) : undefined,\n };\n }\n\n /**\n * Get quotes from all DEXes\n */\n async getAllQuotes(params: QuoteParams): Promise<QuoteResult[]> {\n const queryParams = new URLSearchParams({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n allDexes: 'true',\n });\n\n const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Prepare a swap transaction (returns unsigned transaction data)\n */\n async prepareSwap(params: SwapParams): Promise<{\n to: string;\n data: string;\n value: string;\n gasLimit?: string;\n }> {\n const body: any = {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n slippagePercent: params.slippagePercent ?? 0.5,\n recipient: params.recipient,\n };\n\n if (this.partnerAddress && this.partnerFeeBps) {\n body.partner = this.partnerAddress;\n body.partnerFeeBps = this.partnerFeeBps;\n }\n\n const response = await fetch(`${this.apiUrl}/swap/prepare`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Execute a swap (requires signer - use with ethers.js or viem)\n * \n * @example\n * // With ethers.js\n * const router = new AvaxRouter();\n * const signer = await ethers.getSigner();\n * const result = await router.swap({ tokenIn: 'AVAX', tokenOut: 'USDC', amountIn: '1.0' }, signer);\n */\n async swap(params: SwapParams, signer: any): Promise<SwapResult> {\n // Prepare the transaction\n const txData = await this.prepareSwap(params);\n \n // Execute via signer\n const tx = await signer.sendTransaction({\n to: txData.to,\n data: txData.data,\n value: txData.value,\n });\n\n // Wait for confirmation\n const receipt = await tx.wait();\n\n return {\n txHash: receipt.hash,\n amountIn: params.amountIn,\n amountOut: '0', // Would need to parse from logs\n dexUsed: 'unknown', // Would need to parse from logs\n protocolFee: '0',\n };\n }\n\n /**\n * Get the status of a swap transaction\n */\n async getSwapStatus(txHash: string): Promise<SwapStatus> {\n const response = await fetch(`${this.apiUrl}/swap/status/${txHash}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n const data = await response.json();\n \n return {\n ...data,\n gasUsed: data.gasUsed ? BigInt(data.gasUsed) : undefined,\n };\n }\n\n /**\n * Get list of supported tokens\n */\n async getSupportedTokens(): Promise<Array<{\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n logoURI?: string;\n }>> {\n const response = await fetch(`${this.apiUrl}/tokens`);\n \n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Get list of supported DEXes\n */\n async getSupportedDexes(): Promise<Array<{\n name: string;\n adapter: string;\n version: string;\n }>> {\n const response = await fetch(`${this.apiUrl}/dexes`);\n \n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n return response.json();\n }\n}\n\n// Export singleton for convenience\nlet defaultClient: AvaxRouter | null = null;\n\nexport function getClient(config?: AvaxRouterConfig): AvaxRouter {\n if (!defaultClient || config) {\n defaultClient = new AvaxRouter(config);\n }\n return defaultClient;\n}"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// src/types.ts
|
|
2
|
+
var AVALANCHE_TOKENS = {
|
|
3
|
+
AVAX: "0x0000000000000000000000000000000000000000",
|
|
4
|
+
WAVAX: "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",
|
|
5
|
+
USDC: "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",
|
|
6
|
+
USDT: "0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7",
|
|
7
|
+
JOE: "0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd",
|
|
8
|
+
PNG: "0x60781C2586D68229fde47564546784ab3fACA982"
|
|
9
|
+
};
|
|
10
|
+
var DEX_ROUTER_ADDRESS = "0xYourDeployedContractAddress";
|
|
11
|
+
var API_ENDPOINTS = {
|
|
12
|
+
mainnet: "https://api.avaxrouter.com",
|
|
13
|
+
testnet: "https://api-testnet.avaxrouter.com",
|
|
14
|
+
local: "http://localhost:3000"
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// src/client.ts
|
|
18
|
+
var AvaxRouter = class {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
this.apiUrl = config.apiUrl || API_ENDPOINTS.mainnet;
|
|
21
|
+
this.partnerId = config.partnerId;
|
|
22
|
+
this.partnerFeeBps = config.partnerFeeBps;
|
|
23
|
+
this.partnerAddress = config.partnerAddress;
|
|
24
|
+
if (this.partnerFeeBps && this.partnerFeeBps > 50) {
|
|
25
|
+
throw new Error("Partner fee cannot exceed 50 basis points (0.50%)");
|
|
26
|
+
}
|
|
27
|
+
if (this.partnerFeeBps && !this.partnerAddress) {
|
|
28
|
+
throw new Error("Partner address required when partner fee is set");
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get the best quote across all DEXes
|
|
33
|
+
*/
|
|
34
|
+
async getBestQuote(params) {
|
|
35
|
+
const queryParams = new URLSearchParams({
|
|
36
|
+
tokenIn: params.tokenIn,
|
|
37
|
+
tokenOut: params.tokenOut,
|
|
38
|
+
amountIn: params.amountIn
|
|
39
|
+
});
|
|
40
|
+
if (this.partnerId) {
|
|
41
|
+
queryParams.append("partnerId", this.partnerId);
|
|
42
|
+
}
|
|
43
|
+
const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
46
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
47
|
+
}
|
|
48
|
+
const data = await response.json();
|
|
49
|
+
return {
|
|
50
|
+
...data,
|
|
51
|
+
amountIn: BigInt(data.amountIn),
|
|
52
|
+
amountOut: BigInt(data.amountOut),
|
|
53
|
+
allQuotes: data.allQuotes.map((q) => ({
|
|
54
|
+
...q,
|
|
55
|
+
amountOut: BigInt(q.amountOut)
|
|
56
|
+
})),
|
|
57
|
+
estimatedGas: data.estimatedGas ? BigInt(data.estimatedGas) : void 0
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get quotes from all DEXes
|
|
62
|
+
*/
|
|
63
|
+
async getAllQuotes(params) {
|
|
64
|
+
const queryParams = new URLSearchParams({
|
|
65
|
+
tokenIn: params.tokenIn,
|
|
66
|
+
tokenOut: params.tokenOut,
|
|
67
|
+
amountIn: params.amountIn,
|
|
68
|
+
allDexes: "true"
|
|
69
|
+
});
|
|
70
|
+
const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
73
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
74
|
+
}
|
|
75
|
+
return response.json();
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Prepare a swap transaction (returns unsigned transaction data)
|
|
79
|
+
*/
|
|
80
|
+
async prepareSwap(params) {
|
|
81
|
+
const body = {
|
|
82
|
+
tokenIn: params.tokenIn,
|
|
83
|
+
tokenOut: params.tokenOut,
|
|
84
|
+
amountIn: params.amountIn,
|
|
85
|
+
slippagePercent: params.slippagePercent ?? 0.5,
|
|
86
|
+
recipient: params.recipient
|
|
87
|
+
};
|
|
88
|
+
if (this.partnerAddress && this.partnerFeeBps) {
|
|
89
|
+
body.partner = this.partnerAddress;
|
|
90
|
+
body.partnerFeeBps = this.partnerFeeBps;
|
|
91
|
+
}
|
|
92
|
+
const response = await fetch(`${this.apiUrl}/swap/prepare`, {
|
|
93
|
+
method: "POST",
|
|
94
|
+
headers: { "Content-Type": "application/json" },
|
|
95
|
+
body: JSON.stringify(body)
|
|
96
|
+
});
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
99
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
100
|
+
}
|
|
101
|
+
return response.json();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Execute a swap (requires signer - use with ethers.js or viem)
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* // With ethers.js
|
|
108
|
+
* const router = new AvaxRouter();
|
|
109
|
+
* const signer = await ethers.getSigner();
|
|
110
|
+
* const result = await router.swap({ tokenIn: 'AVAX', tokenOut: 'USDC', amountIn: '1.0' }, signer);
|
|
111
|
+
*/
|
|
112
|
+
async swap(params, signer) {
|
|
113
|
+
const txData = await this.prepareSwap(params);
|
|
114
|
+
const tx = await signer.sendTransaction({
|
|
115
|
+
to: txData.to,
|
|
116
|
+
data: txData.data,
|
|
117
|
+
value: txData.value
|
|
118
|
+
});
|
|
119
|
+
const receipt = await tx.wait();
|
|
120
|
+
return {
|
|
121
|
+
txHash: receipt.hash,
|
|
122
|
+
amountIn: params.amountIn,
|
|
123
|
+
amountOut: "0",
|
|
124
|
+
// Would need to parse from logs
|
|
125
|
+
dexUsed: "unknown",
|
|
126
|
+
// Would need to parse from logs
|
|
127
|
+
protocolFee: "0"
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get the status of a swap transaction
|
|
132
|
+
*/
|
|
133
|
+
async getSwapStatus(txHash) {
|
|
134
|
+
const response = await fetch(`${this.apiUrl}/swap/status/${txHash}`);
|
|
135
|
+
if (!response.ok) {
|
|
136
|
+
const error = await response.json().catch(() => ({ message: "Unknown error" }));
|
|
137
|
+
throw new Error(error.message || `API error: ${response.status}`);
|
|
138
|
+
}
|
|
139
|
+
const data = await response.json();
|
|
140
|
+
return {
|
|
141
|
+
...data,
|
|
142
|
+
gasUsed: data.gasUsed ? BigInt(data.gasUsed) : void 0
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get list of supported tokens
|
|
147
|
+
*/
|
|
148
|
+
async getSupportedTokens() {
|
|
149
|
+
const response = await fetch(`${this.apiUrl}/tokens`);
|
|
150
|
+
if (!response.ok) {
|
|
151
|
+
throw new Error(`API error: ${response.status}`);
|
|
152
|
+
}
|
|
153
|
+
return response.json();
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get list of supported DEXes
|
|
157
|
+
*/
|
|
158
|
+
async getSupportedDexes() {
|
|
159
|
+
const response = await fetch(`${this.apiUrl}/dexes`);
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
throw new Error(`API error: ${response.status}`);
|
|
162
|
+
}
|
|
163
|
+
return response.json();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
var defaultClient = null;
|
|
167
|
+
function getClient(config) {
|
|
168
|
+
if (!defaultClient || config) {
|
|
169
|
+
defaultClient = new AvaxRouter(config);
|
|
170
|
+
}
|
|
171
|
+
return defaultClient;
|
|
172
|
+
}
|
|
173
|
+
export {
|
|
174
|
+
API_ENDPOINTS,
|
|
175
|
+
AVALANCHE_TOKENS,
|
|
176
|
+
AvaxRouter,
|
|
177
|
+
DEX_ROUTER_ADDRESS,
|
|
178
|
+
getClient
|
|
179
|
+
};
|
|
180
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/client.ts"],"sourcesContent":["/**\n * AVAX Router SDK Types\n */\n\nexport interface AvaxRouterConfig {\n /** API base URL (default: https://api.avaxrouter.com) */\n apiUrl?: string;\n /** Partner ID for fee sharing */\n partnerId?: string;\n /** Partner fee in basis points (max 50 = 0.50%) */\n partnerFeeBps?: number;\n /** Partner address to receive fees */\n partnerAddress?: string;\n}\n\nexport interface TokenInfo {\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n logoURI?: string;\n}\n\nexport interface QuoteParams {\n /** Input token address or symbol */\n tokenIn: string;\n /** Output token address or symbol */\n tokenOut: string;\n /** Amount of input tokens (in human-readable format) */\n amountIn: string;\n}\n\nexport interface QuoteResult {\n /** Input token address */\n tokenIn: string;\n /** Output token address */\n tokenOut: string;\n /** Amount in (raw) */\n amountIn: bigint;\n /** Expected amount out (raw) */\n amountOut: bigint;\n /** Amount out formatted for display */\n amountOutFormatted: string;\n /** Best DEX for this route */\n bestDex: string;\n /** All quotes from different DEXes */\n allQuotes: DexQuote[];\n /** Price impact */\n priceImpact?: number;\n /** Route path (for multi-hop) */\n route?: string[];\n /** Protocol fee in basis points */\n protocolFeeBps: number;\n /** Partner fee in basis points (if applicable) */\n partnerFeeBps?: number;\n /** Estimated gas cost */\n estimatedGas?: bigint;\n}\n\nexport interface DexQuote {\n /** DEX name */\n dex: string;\n /** Output amount (raw) */\n amountOut: bigint;\n /** Output amount formatted */\n amountOutFormatted: string;\n /** Whether this quote is the best */\n isBest: boolean;\n}\n\nexport interface SwapParams extends QuoteParams {\n /** Minimum output amount (slippage protection) */\n minAmountOut?: string;\n /** Slippage tolerance in percent (default: 0.5) */\n slippagePercent?: number;\n /** Recipient address (defaults to connected wallet) */\n recipient?: string;\n /** Deadline in seconds (default: 1200 = 20 min) */\n deadline?: number;\n}\n\nexport interface SwapResult {\n /** Transaction hash */\n txHash: string;\n /** Amount of tokens swapped */\n amountIn: string;\n /** Amount of tokens received */\n amountOut: string;\n /** DEX used for the swap */\n dexUsed: string;\n /** Protocol fee paid */\n protocolFee: string;\n /** Partner fee paid (if applicable) */\n partnerFee?: string;\n}\n\nexport interface SwapStatus {\n status: 'pending' | 'confirmed' | 'failed';\n txHash?: string;\n blockNumber?: number;\n gasUsed?: bigint;\n amountIn?: string;\n amountOut?: string;\n error?: string;\n}\n\n// Avalanche token addresses\nexport const AVALANCHE_TOKENS = {\n AVAX: '0x0000000000000000000000000000000000000000',\n WAVAX: '0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7',\n USDC: '0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E',\n USDT: '0x9702230A8Ea53601f5cD2dc00fDBc13d4dF4A8c7',\n JOE: '0x6e84a6216eA6dACC71eE8E6b0a5B7322EEbC0fDd',\n PNG: '0x60781C2586D68229fde47564546784ab3fACA982',\n} as const;\n\n// DexRouter contract address on Avalanche\nexport const DEX_ROUTER_ADDRESS = '0xYourDeployedContractAddress' as `0x${string}`;\n\n// API endpoints\nexport const API_ENDPOINTS = {\n mainnet: 'https://api.avaxrouter.com',\n testnet: 'https://api-testnet.avaxrouter.com',\n local: 'http://localhost:3000',\n} as const;","/**\n * AVAX Router SDK Client\n * \n * Main entry point for interacting with AVAX Router\n */\n\nimport {\n AvaxRouterConfig,\n QuoteParams,\n QuoteResult,\n SwapParams,\n SwapResult,\n SwapStatus,\n API_ENDPOINTS,\n} from './types';\n\nexport class AvaxRouter {\n private apiUrl: string;\n private partnerId?: string;\n private partnerFeeBps?: number;\n private partnerAddress?: string;\n\n constructor(config: AvaxRouterConfig = {}) {\n this.apiUrl = config.apiUrl || API_ENDPOINTS.mainnet;\n this.partnerId = config.partnerId;\n this.partnerFeeBps = config.partnerFeeBps;\n this.partnerAddress = config.partnerAddress;\n\n // Validate partner config\n if (this.partnerFeeBps && this.partnerFeeBps > 50) {\n throw new Error('Partner fee cannot exceed 50 basis points (0.50%)');\n }\n if (this.partnerFeeBps && !this.partnerAddress) {\n throw new Error('Partner address required when partner fee is set');\n }\n }\n\n /**\n * Get the best quote across all DEXes\n */\n async getBestQuote(params: QuoteParams): Promise<QuoteResult> {\n const queryParams = new URLSearchParams({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n });\n\n if (this.partnerId) {\n queryParams.append('partnerId', this.partnerId);\n }\n\n const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n const data = await response.json();\n \n return {\n ...data,\n amountIn: BigInt(data.amountIn),\n amountOut: BigInt(data.amountOut),\n allQuotes: data.allQuotes.map((q: any) => ({\n ...q,\n amountOut: BigInt(q.amountOut),\n })),\n estimatedGas: data.estimatedGas ? BigInt(data.estimatedGas) : undefined,\n };\n }\n\n /**\n * Get quotes from all DEXes\n */\n async getAllQuotes(params: QuoteParams): Promise<QuoteResult[]> {\n const queryParams = new URLSearchParams({\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n allDexes: 'true',\n });\n\n const response = await fetch(`${this.apiUrl}/quote?${queryParams}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Prepare a swap transaction (returns unsigned transaction data)\n */\n async prepareSwap(params: SwapParams): Promise<{\n to: string;\n data: string;\n value: string;\n gasLimit?: string;\n }> {\n const body: any = {\n tokenIn: params.tokenIn,\n tokenOut: params.tokenOut,\n amountIn: params.amountIn,\n slippagePercent: params.slippagePercent ?? 0.5,\n recipient: params.recipient,\n };\n\n if (this.partnerAddress && this.partnerFeeBps) {\n body.partner = this.partnerAddress;\n body.partnerFeeBps = this.partnerFeeBps;\n }\n\n const response = await fetch(`${this.apiUrl}/swap/prepare`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Execute a swap (requires signer - use with ethers.js or viem)\n * \n * @example\n * // With ethers.js\n * const router = new AvaxRouter();\n * const signer = await ethers.getSigner();\n * const result = await router.swap({ tokenIn: 'AVAX', tokenOut: 'USDC', amountIn: '1.0' }, signer);\n */\n async swap(params: SwapParams, signer: any): Promise<SwapResult> {\n // Prepare the transaction\n const txData = await this.prepareSwap(params);\n \n // Execute via signer\n const tx = await signer.sendTransaction({\n to: txData.to,\n data: txData.data,\n value: txData.value,\n });\n\n // Wait for confirmation\n const receipt = await tx.wait();\n\n return {\n txHash: receipt.hash,\n amountIn: params.amountIn,\n amountOut: '0', // Would need to parse from logs\n dexUsed: 'unknown', // Would need to parse from logs\n protocolFee: '0',\n };\n }\n\n /**\n * Get the status of a swap transaction\n */\n async getSwapStatus(txHash: string): Promise<SwapStatus> {\n const response = await fetch(`${this.apiUrl}/swap/status/${txHash}`);\n \n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Unknown error' }));\n throw new Error(error.message || `API error: ${response.status}`);\n }\n\n const data = await response.json();\n \n return {\n ...data,\n gasUsed: data.gasUsed ? BigInt(data.gasUsed) : undefined,\n };\n }\n\n /**\n * Get list of supported tokens\n */\n async getSupportedTokens(): Promise<Array<{\n address: string;\n symbol: string;\n name: string;\n decimals: number;\n logoURI?: string;\n }>> {\n const response = await fetch(`${this.apiUrl}/tokens`);\n \n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n return response.json();\n }\n\n /**\n * Get list of supported DEXes\n */\n async getSupportedDexes(): Promise<Array<{\n name: string;\n adapter: string;\n version: string;\n }>> {\n const response = await fetch(`${this.apiUrl}/dexes`);\n \n if (!response.ok) {\n throw new Error(`API error: ${response.status}`);\n }\n\n return response.json();\n }\n}\n\n// Export singleton for convenience\nlet defaultClient: AvaxRouter | null = null;\n\nexport function getClient(config?: AvaxRouterConfig): AvaxRouter {\n if (!defaultClient || config) {\n defaultClient = new AvaxRouter(config);\n }\n return defaultClient;\n}"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AVAX Router SDK Types
|
|
3
|
+
*/
|
|
4
|
+
interface AvaxRouterConfig {
|
|
5
|
+
/** API base URL (default: https://api.avaxrouter.com) */
|
|
6
|
+
apiUrl?: string;
|
|
7
|
+
/** Partner ID for fee sharing */
|
|
8
|
+
partnerId?: string;
|
|
9
|
+
/** Partner fee in basis points (max 50 = 0.50%) */
|
|
10
|
+
partnerFeeBps?: number;
|
|
11
|
+
/** Partner address to receive fees */
|
|
12
|
+
partnerAddress?: string;
|
|
13
|
+
}
|
|
14
|
+
interface QuoteParams {
|
|
15
|
+
/** Input token address or symbol */
|
|
16
|
+
tokenIn: string;
|
|
17
|
+
/** Output token address or symbol */
|
|
18
|
+
tokenOut: string;
|
|
19
|
+
/** Amount of input tokens (in human-readable format) */
|
|
20
|
+
amountIn: string;
|
|
21
|
+
}
|
|
22
|
+
interface QuoteResult {
|
|
23
|
+
/** Input token address */
|
|
24
|
+
tokenIn: string;
|
|
25
|
+
/** Output token address */
|
|
26
|
+
tokenOut: string;
|
|
27
|
+
/** Amount in (raw) */
|
|
28
|
+
amountIn: bigint;
|
|
29
|
+
/** Expected amount out (raw) */
|
|
30
|
+
amountOut: bigint;
|
|
31
|
+
/** Amount out formatted for display */
|
|
32
|
+
amountOutFormatted: string;
|
|
33
|
+
/** Best DEX for this route */
|
|
34
|
+
bestDex: string;
|
|
35
|
+
/** All quotes from different DEXes */
|
|
36
|
+
allQuotes: DexQuote[];
|
|
37
|
+
/** Price impact */
|
|
38
|
+
priceImpact?: number;
|
|
39
|
+
/** Route path (for multi-hop) */
|
|
40
|
+
route?: string[];
|
|
41
|
+
/** Protocol fee in basis points */
|
|
42
|
+
protocolFeeBps: number;
|
|
43
|
+
/** Partner fee in basis points (if applicable) */
|
|
44
|
+
partnerFeeBps?: number;
|
|
45
|
+
/** Estimated gas cost */
|
|
46
|
+
estimatedGas?: bigint;
|
|
47
|
+
}
|
|
48
|
+
interface DexQuote {
|
|
49
|
+
/** DEX name */
|
|
50
|
+
dex: string;
|
|
51
|
+
/** Output amount (raw) */
|
|
52
|
+
amountOut: bigint;
|
|
53
|
+
/** Output amount formatted */
|
|
54
|
+
amountOutFormatted: string;
|
|
55
|
+
/** Whether this quote is the best */
|
|
56
|
+
isBest: boolean;
|
|
57
|
+
}
|
|
58
|
+
interface SwapParams extends QuoteParams {
|
|
59
|
+
/** Minimum output amount (slippage protection) */
|
|
60
|
+
minAmountOut?: string;
|
|
61
|
+
/** Slippage tolerance in percent (default: 0.5) */
|
|
62
|
+
slippagePercent?: number;
|
|
63
|
+
/** Recipient address (defaults to connected wallet) */
|
|
64
|
+
recipient?: string;
|
|
65
|
+
/** Deadline in seconds (default: 1200 = 20 min) */
|
|
66
|
+
deadline?: number;
|
|
67
|
+
}
|
|
68
|
+
interface SwapResult {
|
|
69
|
+
/** Transaction hash */
|
|
70
|
+
txHash: string;
|
|
71
|
+
/** Amount of tokens swapped */
|
|
72
|
+
amountIn: string;
|
|
73
|
+
/** Amount of tokens received */
|
|
74
|
+
amountOut: string;
|
|
75
|
+
/** DEX used for the swap */
|
|
76
|
+
dexUsed: string;
|
|
77
|
+
/** Protocol fee paid */
|
|
78
|
+
protocolFee: string;
|
|
79
|
+
/** Partner fee paid (if applicable) */
|
|
80
|
+
partnerFee?: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* useQuote Hook
|
|
85
|
+
*
|
|
86
|
+
* Fetch the best quote for a token swap
|
|
87
|
+
*/
|
|
88
|
+
|
|
89
|
+
interface UseQuoteOptions extends QuoteParams {
|
|
90
|
+
/** SDK configuration */
|
|
91
|
+
config?: AvaxRouterConfig;
|
|
92
|
+
/** Auto-fetch on mount (default: true) */
|
|
93
|
+
autoFetch?: boolean;
|
|
94
|
+
/** Refresh interval in ms (default: 10000) */
|
|
95
|
+
refreshInterval?: number;
|
|
96
|
+
}
|
|
97
|
+
interface UseQuoteResult {
|
|
98
|
+
/** Quote result */
|
|
99
|
+
quote: QuoteResult | null;
|
|
100
|
+
/** Loading state */
|
|
101
|
+
loading: boolean;
|
|
102
|
+
/** Error if any */
|
|
103
|
+
error: Error | null;
|
|
104
|
+
/** Manually refetch */
|
|
105
|
+
refetch: () => Promise<void>;
|
|
106
|
+
}
|
|
107
|
+
declare function useQuote(options: UseQuoteOptions): UseQuoteResult;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* useSwap Hook
|
|
111
|
+
*
|
|
112
|
+
* Execute a token swap
|
|
113
|
+
*/
|
|
114
|
+
|
|
115
|
+
interface UseSwapOptions {
|
|
116
|
+
/** SDK configuration */
|
|
117
|
+
config?: AvaxRouterConfig;
|
|
118
|
+
}
|
|
119
|
+
interface UseSwapResult {
|
|
120
|
+
/** Execute the swap */
|
|
121
|
+
swap: (params: SwapParams, signer: any) => Promise<SwapResult>;
|
|
122
|
+
/** Transaction hash after swap */
|
|
123
|
+
txHash: string | null;
|
|
124
|
+
/** Loading state */
|
|
125
|
+
loading: boolean;
|
|
126
|
+
/** Error if any */
|
|
127
|
+
error: Error | null;
|
|
128
|
+
/** Reset state */
|
|
129
|
+
reset: () => void;
|
|
130
|
+
}
|
|
131
|
+
declare function useSwap(options?: UseSwapOptions): UseSwapResult;
|
|
132
|
+
|
|
133
|
+
export { type AvaxRouterConfig, type QuoteParams, type QuoteResult, type SwapParams, type SwapResult, type UseQuoteOptions, type UseQuoteResult, type UseSwapOptions, type UseSwapResult, useQuote, useSwap };
|