@deserialize/swap-sdk 0.0.341 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/swapSDK.d.ts +124 -48
- package/dist/swapSDK.js +137 -62
- package/dist/swapSDK.js.map +1 -1
- package/package.json +1 -1
- package/src/swapSDK.ts +194 -73
package/dist/swapSDK.d.ts
CHANGED
@@ -3,16 +3,16 @@ import web3, { Connection, Keypair, PublicKey, TransactionInstruction, Versioned
|
|
3
3
|
* Parameters to request a swap.
|
4
4
|
*/
|
5
5
|
export interface SwapRequestParams {
|
6
|
-
/** User
|
6
|
+
/** User's public key */
|
7
7
|
publicKey: PublicKey;
|
8
|
-
/** Token A
|
8
|
+
/** Token A's address */
|
9
9
|
tokenA: PublicKey;
|
10
|
-
/** Token B
|
10
|
+
/** Token B's address */
|
11
11
|
tokenB: PublicKey;
|
12
12
|
/** Amount of Token A to swap (in human-readable units) */
|
13
13
|
amountIn: number;
|
14
|
-
/** DEX identifier –
|
15
|
-
dexId:
|
14
|
+
/** DEX identifier – "INVARIANT", "ORCA", or "ALL" */
|
15
|
+
dexId: DexIdTypes;
|
16
16
|
/**
|
17
17
|
* This is used to set options like limit the swap to just two hops to
|
18
18
|
* prevent errors like TooManyAccountLocks
|
@@ -30,26 +30,28 @@ export type GetTokenMintBalanceType = {
|
|
30
30
|
* Result from the swapTx method.
|
31
31
|
*/
|
32
32
|
export interface SwapTxResult {
|
33
|
-
/**
|
33
|
+
/** Fully constructed VersionedTransaction ready for signing */
|
34
34
|
transaction: VersionedTransaction;
|
35
|
-
/**
|
35
|
+
/** Raw transaction data in base64 encoding */
|
36
|
+
serializedTransactions: string;
|
37
|
+
/** Output amount in token decimals */
|
36
38
|
amountOut: number;
|
37
|
-
/**
|
39
|
+
/** Human-readable output amount */
|
38
40
|
amountOutUi: number;
|
39
|
-
/**
|
40
|
-
|
41
|
+
/** Price of Token A in terms of Token B */
|
42
|
+
pairPrice: number;
|
43
|
+
/** Swap route details */
|
44
|
+
routePlan: Array<{
|
41
45
|
tokenA: PublicKey;
|
42
46
|
tokenB: PublicKey;
|
43
|
-
dexId:
|
44
|
-
}
|
45
|
-
/**
|
47
|
+
dexId: DexIdTypes;
|
48
|
+
}>;
|
49
|
+
/** Associated lookup accounts */
|
46
50
|
lookupAccounts: PublicKey[];
|
47
|
-
/**
|
51
|
+
/** Required transaction signers */
|
48
52
|
signers: Keypair[];
|
49
|
-
/**
|
50
|
-
pairPrice: number;
|
53
|
+
/** Protocol fee percentage */
|
51
54
|
feeRate: number;
|
52
|
-
serializedTransactions: string;
|
53
55
|
}
|
54
56
|
/**
|
55
57
|
* Structure representing a group of instructions from the API.
|
@@ -83,6 +85,24 @@ export interface SwapIxResult {
|
|
83
85
|
/** Any top-level signers returned (as base64 encoded strings) */
|
84
86
|
signers: string[];
|
85
87
|
}
|
88
|
+
/**
|
89
|
+
* Response from the quote endpoint
|
90
|
+
*/
|
91
|
+
export interface QuoteResponse {
|
92
|
+
tokenA: string;
|
93
|
+
tokenB: string;
|
94
|
+
amountIn: string;
|
95
|
+
amountOut: string;
|
96
|
+
tokenPrice: string;
|
97
|
+
priceImpact: string;
|
98
|
+
feeRate: string;
|
99
|
+
routePlan: Array<{
|
100
|
+
tokenA: string;
|
101
|
+
tokenB: string;
|
102
|
+
dexId: DexIdTypes;
|
103
|
+
}>;
|
104
|
+
dexId: DexIdTypes;
|
105
|
+
}
|
86
106
|
/**
|
87
107
|
* Token details returned from the /tokenList endpoint.
|
88
108
|
*/
|
@@ -96,54 +116,82 @@ export interface Token {
|
|
96
116
|
tokenProgram: string;
|
97
117
|
}
|
98
118
|
/**
|
99
|
-
*
|
119
|
+
* Balance Check Parameters
|
120
|
+
*/
|
121
|
+
export interface BalanceCheckParams {
|
122
|
+
/** User's wallet address in base58 */
|
123
|
+
userAddress: string;
|
124
|
+
/** Token mint addresses to check */
|
125
|
+
tokenMints: string[];
|
126
|
+
}
|
127
|
+
/**
|
128
|
+
* SwapSDK simplifies interaction with the decentralized exchange API, handling swaps, token data, and balance checks.
|
129
|
+
*
|
130
|
+
* Key Features:
|
131
|
+
* - Get swap quotes to preview expected outcomes
|
132
|
+
* - Build swap transactions with automatic route finding
|
133
|
+
* - Get underlying swap instructions for custom transaction handling
|
134
|
+
* - Retrieve token list and price data
|
135
|
+
* - Check token balances
|
136
|
+
* - Transaction simulation
|
100
137
|
*
|
101
138
|
* Usage:
|
102
139
|
* ```ts
|
103
|
-
* import { SwapSDK } from "./SwapSDK";
|
104
|
-
* import { PublicKey } from "@solana/web3.js";
|
140
|
+
* import { SwapSDK, DEX_IDS } from "./SwapSDK";
|
141
|
+
* import { PublicKey, Connection } from "@solana/web3.js";
|
105
142
|
*
|
106
|
-
* const sdk = new SwapSDK(
|
143
|
+
* const sdk = new SwapSDK(); // Uses default production URL
|
144
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
107
145
|
*
|
108
|
-
* async function
|
109
|
-
*
|
110
|
-
*
|
146
|
+
* async function fullSwapFlow() {
|
147
|
+
* // Example swap parameters
|
148
|
+
* const swapParams = {
|
149
|
+
* publicKey: new PublicKey("UserPublicKeyBase58"),
|
111
150
|
* tokenA: new PublicKey("GU7NS9xCwgNPiAdJ69iusFrRfawjDDPjeMBovhV1d4kn"),
|
112
151
|
* tokenB: new PublicKey("CEBP3CqAbW4zdZA57H2wfaSG1QNdzQ72GiQEbQXyW9Tm"),
|
113
152
|
* amountIn: 10.0,
|
114
|
-
* dexId:
|
153
|
+
* dexId: DEX_IDS.INVARIANT,
|
154
|
+
* options: { reduceToTwoHops: false }
|
115
155
|
* };
|
116
156
|
*
|
117
|
-
* //
|
118
|
-
* const
|
119
|
-
* console.log("
|
157
|
+
* // Get a quote first to see expected outcome
|
158
|
+
* const quote = await sdk.getSwapQuote(swapParams);
|
159
|
+
* console.log("Expected output amount:", quote.amountOut);
|
160
|
+
* console.log("Price impact:", quote.priceImpact);
|
120
161
|
*
|
121
|
-
* //
|
122
|
-
* const
|
123
|
-
*
|
162
|
+
* // Get complete swap transaction
|
163
|
+
* const txResult = await sdk.swapTx({
|
164
|
+
* ...swapParams,
|
165
|
+
* quote: quote
|
166
|
+
* });
|
167
|
+
* console.log("Serialized Transaction:", txResult.serializedTransactions);
|
124
168
|
*
|
125
|
-
* //
|
169
|
+
* // Simulate transaction before sending
|
170
|
+
* const simulation = await sdk.simulateTransaction(connection, txResult.transaction);
|
171
|
+
* console.log("Simulation Result:", simulation);
|
172
|
+
*
|
173
|
+
* // Get token list
|
126
174
|
* const tokens = await sdk.tokenList();
|
127
|
-
* console.log("Tokens:", tokens);
|
175
|
+
* console.log("Available Tokens:", tokens);
|
176
|
+
*
|
177
|
+
* // Check balances
|
178
|
+
* const balances = await sdk.getTokenMintBalance({
|
179
|
+
* userAddress: swapParams.publicKey.toBase58(),
|
180
|
+
* tokenMints: [swapParams.tokenA.toBase58(), swapParams.tokenB.toBase58()]
|
181
|
+
* });
|
182
|
+
* console.log("User Balances:", balances);
|
128
183
|
*
|
129
|
-
* //
|
130
|
-
* const
|
131
|
-
* console.log("
|
184
|
+
* // Get token price
|
185
|
+
* const solPrice = await sdk.tokenPrice("So11111111111111111111111111111111111111112");
|
186
|
+
* console.log("SOL Price:", solPrice);
|
132
187
|
* }
|
133
188
|
*
|
134
|
-
*
|
189
|
+
* fullSwapFlow();
|
135
190
|
* ```
|
136
191
|
*/
|
137
192
|
export declare class SwapSDK {
|
138
193
|
private baseUrl;
|
139
194
|
constructor(baseUrl?: string);
|
140
|
-
/**
|
141
|
-
* Calls the bestSwapRoute endpoint with the provided parameters.
|
142
|
-
*
|
143
|
-
* @param params Swap parameters.
|
144
|
-
* @returns The JSON-parsed API response.
|
145
|
-
*/
|
146
|
-
private callSwapEndpoint;
|
147
195
|
base58: import("base-x").default.BaseConverter;
|
148
196
|
web3: typeof web3;
|
149
197
|
DEX_IDS: {
|
@@ -151,8 +199,26 @@ export declare class SwapSDK {
|
|
151
199
|
readonly INVARIANT: "INVARIANT";
|
152
200
|
readonly ALL: "ALL";
|
153
201
|
};
|
202
|
+
/**
|
203
|
+
* Gets a swap quote without executing the swap
|
204
|
+
*
|
205
|
+
* @param params Swap parameters
|
206
|
+
* @returns Quote information including expected output amount and price impact
|
207
|
+
*/
|
208
|
+
getSwapQuote(params: SwapRequestParams): Promise<QuoteResponse>;
|
209
|
+
/**
|
210
|
+
* Executes a swap based on a previously obtained quote
|
211
|
+
*
|
212
|
+
* @param params Swap parameters including the quote
|
213
|
+
* @returns Transaction and output details
|
214
|
+
*/
|
215
|
+
executeSwap(params: {
|
216
|
+
publicKey: PublicKey;
|
217
|
+
quote: QuoteResponse;
|
218
|
+
}): Promise<any>;
|
154
219
|
/**
|
155
220
|
* Calls the swap endpoint and returns a fully constructed Transaction.
|
221
|
+
* This method is a wrapper that gets a quote first, then executes the swap.
|
156
222
|
*
|
157
223
|
* @param params Swap parameters.
|
158
224
|
* @returns A promise that resolves to a SwapTxResult.
|
@@ -160,6 +226,7 @@ export declare class SwapSDK {
|
|
160
226
|
swapTx(params: SwapRequestParams): Promise<SwapTxResult>;
|
161
227
|
/**
|
162
228
|
* Calls the swap endpoint and returns the raw instructions and related data.
|
229
|
+
* This method is a wrapper that gets a quote first, then executes the swap to get instructions.
|
163
230
|
*
|
164
231
|
* @param params Swap parameters.
|
165
232
|
* @returns A promise that resolves to a SwapIxResult.
|
@@ -178,10 +245,19 @@ export declare class SwapSDK {
|
|
178
245
|
* @returns A promise that resolves to the token's price (number).
|
179
246
|
*/
|
180
247
|
tokenPrice(tokenAddress: string): Promise<number>;
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
248
|
+
/**
|
249
|
+
* Gets the token balances for a given wallet
|
250
|
+
*
|
251
|
+
* @param params User address and token mints to check
|
252
|
+
* @returns Array of token balances
|
253
|
+
*/
|
254
|
+
getTokenMintBalance(params: BalanceCheckParams): Promise<GetTokenMintBalanceType[]>;
|
255
|
+
/**
|
256
|
+
* Health check for the API
|
257
|
+
*
|
258
|
+
* @returns A string "Pong" if the service is operational
|
259
|
+
*/
|
260
|
+
ping(): Promise<string>;
|
185
261
|
/**
|
186
262
|
* Simulates a transaction.
|
187
263
|
* @param connection The connection to use.
|
package/dist/swapSDK.js
CHANGED
@@ -42,42 +42,68 @@ const web3_js_1 = __importStar(require("@solana/web3.js"));
|
|
42
42
|
const bs58_1 = __importDefault(require("bs58"));
|
43
43
|
const errors_1 = require("./errors");
|
44
44
|
/**
|
45
|
-
* SwapSDK simplifies
|
45
|
+
* SwapSDK simplifies interaction with the decentralized exchange API, handling swaps, token data, and balance checks.
|
46
|
+
*
|
47
|
+
* Key Features:
|
48
|
+
* - Get swap quotes to preview expected outcomes
|
49
|
+
* - Build swap transactions with automatic route finding
|
50
|
+
* - Get underlying swap instructions for custom transaction handling
|
51
|
+
* - Retrieve token list and price data
|
52
|
+
* - Check token balances
|
53
|
+
* - Transaction simulation
|
46
54
|
*
|
47
55
|
* Usage:
|
48
56
|
* ```ts
|
49
|
-
* import { SwapSDK } from "./SwapSDK";
|
50
|
-
* import { PublicKey } from "@solana/web3.js";
|
57
|
+
* import { SwapSDK, DEX_IDS } from "./SwapSDK";
|
58
|
+
* import { PublicKey, Connection } from "@solana/web3.js";
|
51
59
|
*
|
52
|
-
* const sdk = new SwapSDK(
|
60
|
+
* const sdk = new SwapSDK(); // Uses default production URL
|
61
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
53
62
|
*
|
54
|
-
* async function
|
55
|
-
*
|
56
|
-
*
|
63
|
+
* async function fullSwapFlow() {
|
64
|
+
* // Example swap parameters
|
65
|
+
* const swapParams = {
|
66
|
+
* publicKey: new PublicKey("UserPublicKeyBase58"),
|
57
67
|
* tokenA: new PublicKey("GU7NS9xCwgNPiAdJ69iusFrRfawjDDPjeMBovhV1d4kn"),
|
58
68
|
* tokenB: new PublicKey("CEBP3CqAbW4zdZA57H2wfaSG1QNdzQ72GiQEbQXyW9Tm"),
|
59
69
|
* amountIn: 10.0,
|
60
|
-
* dexId:
|
70
|
+
* dexId: DEX_IDS.INVARIANT,
|
71
|
+
* options: { reduceToTwoHops: false }
|
61
72
|
* };
|
62
73
|
*
|
63
|
-
* //
|
64
|
-
* const
|
65
|
-
* console.log("
|
74
|
+
* // Get a quote first to see expected outcome
|
75
|
+
* const quote = await sdk.getSwapQuote(swapParams);
|
76
|
+
* console.log("Expected output amount:", quote.amountOut);
|
77
|
+
* console.log("Price impact:", quote.priceImpact);
|
78
|
+
*
|
79
|
+
* // Get complete swap transaction
|
80
|
+
* const txResult = await sdk.swapTx({
|
81
|
+
* ...swapParams,
|
82
|
+
* quote: quote
|
83
|
+
* });
|
84
|
+
* console.log("Serialized Transaction:", txResult.serializedTransactions);
|
66
85
|
*
|
67
|
-
* //
|
68
|
-
* const
|
69
|
-
* console.log("
|
86
|
+
* // Simulate transaction before sending
|
87
|
+
* const simulation = await sdk.simulateTransaction(connection, txResult.transaction);
|
88
|
+
* console.log("Simulation Result:", simulation);
|
70
89
|
*
|
71
|
-
* //
|
90
|
+
* // Get token list
|
72
91
|
* const tokens = await sdk.tokenList();
|
73
|
-
* console.log("Tokens:", tokens);
|
92
|
+
* console.log("Available Tokens:", tokens);
|
93
|
+
*
|
94
|
+
* // Check balances
|
95
|
+
* const balances = await sdk.getTokenMintBalance({
|
96
|
+
* userAddress: swapParams.publicKey.toBase58(),
|
97
|
+
* tokenMints: [swapParams.tokenA.toBase58(), swapParams.tokenB.toBase58()]
|
98
|
+
* });
|
99
|
+
* console.log("User Balances:", balances);
|
74
100
|
*
|
75
|
-
* //
|
76
|
-
* const
|
77
|
-
* console.log("
|
101
|
+
* // Get token price
|
102
|
+
* const solPrice = await sdk.tokenPrice("So11111111111111111111111111111111111111112");
|
103
|
+
* console.log("SOL Price:", solPrice);
|
78
104
|
* }
|
79
105
|
*
|
80
|
-
*
|
106
|
+
* fullSwapFlow();
|
81
107
|
* ```
|
82
108
|
*/
|
83
109
|
class SwapSDK {
|
@@ -85,48 +111,46 @@ class SwapSDK {
|
|
85
111
|
this.base58 = bs58_1.default;
|
86
112
|
this.web3 = web3_js_1.default;
|
87
113
|
this.DEX_IDS = exports.DEX_IDS;
|
88
|
-
this.getTokenMintBalance = async (params) => {
|
89
|
-
const body = {
|
90
|
-
userAddress: params.publicKey,
|
91
|
-
tokenMints: params.mints,
|
92
|
-
};
|
93
|
-
try {
|
94
|
-
const response = await fetch(`${this.baseUrl}/getMintBalances`, {
|
95
|
-
method: "POST",
|
96
|
-
headers: {
|
97
|
-
"Content-Type": "application/json",
|
98
|
-
},
|
99
|
-
body: JSON.stringify(body),
|
100
|
-
});
|
101
|
-
if (!response.ok) {
|
102
|
-
throw new Error(`HTTP error! status: ${response.status}`);
|
103
|
-
}
|
104
|
-
const data = await response.json();
|
105
|
-
return data;
|
106
|
-
}
|
107
|
-
catch (error) {
|
108
|
-
console.log(error);
|
109
|
-
}
|
110
|
-
};
|
111
114
|
this.baseUrl = baseUrl || exports.BASE_URL;
|
112
115
|
}
|
113
116
|
/**
|
114
|
-
*
|
117
|
+
* Gets a swap quote without executing the swap
|
115
118
|
*
|
116
|
-
* @param params Swap parameters
|
117
|
-
* @returns
|
119
|
+
* @param params Swap parameters
|
120
|
+
* @returns Quote information including expected output amount and price impact
|
118
121
|
*/
|
119
|
-
async
|
120
|
-
// Prepare the payload by converting PublicKeys to base58 strings
|
122
|
+
async getSwapQuote(params) {
|
121
123
|
const body = {
|
122
|
-
publicKey: params.publicKey.toBase58(),
|
123
124
|
tokenA: params.tokenA.toBase58(),
|
124
125
|
tokenB: params.tokenB.toBase58(),
|
125
126
|
amountIn: params.amountIn.toString(),
|
126
127
|
dexId: params.dexId,
|
127
128
|
options: params.options,
|
128
129
|
};
|
129
|
-
const response = await fetch(`${this.baseUrl}/
|
130
|
+
const response = await fetch(`${this.baseUrl}/quote`, {
|
131
|
+
method: "POST",
|
132
|
+
headers: {
|
133
|
+
"Content-Type": "application/json",
|
134
|
+
},
|
135
|
+
body: JSON.stringify(body),
|
136
|
+
});
|
137
|
+
if (!response.ok) {
|
138
|
+
throw new Error(`API Error: ${response.statusText}`);
|
139
|
+
}
|
140
|
+
return await response.json();
|
141
|
+
}
|
142
|
+
/**
|
143
|
+
* Executes a swap based on a previously obtained quote
|
144
|
+
*
|
145
|
+
* @param params Swap parameters including the quote
|
146
|
+
* @returns Transaction and output details
|
147
|
+
*/
|
148
|
+
async executeSwap(params) {
|
149
|
+
const body = {
|
150
|
+
publicKey: params.publicKey.toBase58(),
|
151
|
+
quote: params.quote,
|
152
|
+
};
|
153
|
+
const response = await fetch(`${this.baseUrl}/swap`, {
|
130
154
|
method: "POST",
|
131
155
|
headers: {
|
132
156
|
"Content-Type": "application/json",
|
@@ -136,54 +160,68 @@ class SwapSDK {
|
|
136
160
|
if (!response.ok) {
|
137
161
|
throw new Error(`API Error: ${response.statusText}`);
|
138
162
|
}
|
139
|
-
return response.json();
|
163
|
+
return await response.json();
|
140
164
|
}
|
141
165
|
/**
|
142
166
|
* Calls the swap endpoint and returns a fully constructed Transaction.
|
167
|
+
* This method is a wrapper that gets a quote first, then executes the swap.
|
143
168
|
*
|
144
169
|
* @param params Swap parameters.
|
145
170
|
* @returns A promise that resolves to a SwapTxResult.
|
146
171
|
*/
|
147
172
|
async swapTx(params) {
|
148
|
-
|
173
|
+
// First get a quote
|
174
|
+
const quote = await this.getSwapQuote(params);
|
175
|
+
// Then execute the swap with the quote
|
176
|
+
const data = await this.executeSwap({
|
177
|
+
publicKey: params.publicKey,
|
178
|
+
quote,
|
179
|
+
});
|
149
180
|
// Convert the base64-encoded transaction into a VersionedTransaction.
|
150
181
|
const txBuffer = Buffer.from(data.transaction, "base64");
|
151
182
|
const transaction = web3_js_1.VersionedTransaction.deserialize(txBuffer);
|
152
183
|
// Convert lookup accounts from strings to PublicKey objects.
|
153
184
|
const lookupAccounts = (data.lookUpAccounts || []).map((addr) => new web3_js_1.PublicKey(addr));
|
154
185
|
// Convert the route plan tokens into PublicKey objects.
|
155
|
-
const routePlan = (
|
186
|
+
const routePlan = (quote.routePlan || []).map((rp) => ({
|
156
187
|
tokenA: new web3_js_1.PublicKey(rp.tokenA),
|
157
188
|
tokenB: new web3_js_1.PublicKey(rp.tokenB),
|
158
189
|
dexId: rp.dexId,
|
159
190
|
}));
|
160
|
-
// Convert each
|
191
|
+
// Convert each base58-encoded signer secret into a Keypair.
|
161
192
|
const signers = data.signers.map((s) => web3_js_1.Keypair.fromSecretKey(bs58_1.default.decode(s)));
|
162
193
|
transaction.sign(signers);
|
163
194
|
return {
|
164
195
|
transaction,
|
165
196
|
serializedTransactions: data.transaction,
|
166
197
|
amountOut: Number(data.amountOut),
|
167
|
-
amountOutUi: Number(
|
168
|
-
pairPrice:
|
198
|
+
amountOutUi: Number(quote.amountOut),
|
199
|
+
pairPrice: Number(quote.tokenPrice),
|
169
200
|
routePlan,
|
170
201
|
lookupAccounts,
|
171
202
|
signers,
|
172
|
-
feeRate: parseFloat(
|
203
|
+
feeRate: parseFloat(quote.feeRate),
|
173
204
|
};
|
174
205
|
}
|
175
206
|
/**
|
176
207
|
* Calls the swap endpoint and returns the raw instructions and related data.
|
208
|
+
* This method is a wrapper that gets a quote first, then executes the swap to get instructions.
|
177
209
|
*
|
178
210
|
* @param params Swap parameters.
|
179
211
|
* @returns A promise that resolves to a SwapIxResult.
|
180
212
|
*/
|
181
213
|
async swapIx(params) {
|
182
|
-
|
214
|
+
// First get a quote
|
215
|
+
const quote = await this.getSwapQuote(params);
|
216
|
+
// Then execute the swap with the quote
|
217
|
+
const data = await this.executeSwap({
|
218
|
+
publicKey: params.publicKey,
|
219
|
+
quote,
|
220
|
+
});
|
183
221
|
// Convert lookup accounts from strings to PublicKey objects.
|
184
222
|
const lookupAccounts = (data.lookUpAccounts || []).map((addr) => new web3_js_1.PublicKey(addr));
|
185
223
|
// Convert the route plan tokens into PublicKey objects.
|
186
|
-
const routePlan = (
|
224
|
+
const routePlan = (quote.routePlan || []).map((rp) => ({
|
187
225
|
tokenA: new web3_js_1.PublicKey(rp.tokenA),
|
188
226
|
tokenB: new web3_js_1.PublicKey(rp.tokenB),
|
189
227
|
dexId: rp.dexId,
|
@@ -197,7 +235,7 @@ class SwapSDK {
|
|
197
235
|
return {
|
198
236
|
instructionGroups,
|
199
237
|
amountOut: Number(data.amountOut),
|
200
|
-
amountOutUi: Number(
|
238
|
+
amountOutUi: Number(quote.amountOut),
|
201
239
|
routePlan,
|
202
240
|
lookupAccounts,
|
203
241
|
signers: data.signers,
|
@@ -214,7 +252,7 @@ class SwapSDK {
|
|
214
252
|
throw new Error(`API Error: ${response.statusText}`);
|
215
253
|
}
|
216
254
|
const data = await response.json();
|
217
|
-
return data.
|
255
|
+
return data.map((token) => ({
|
218
256
|
name: token.metadata.name,
|
219
257
|
symbol: token.metadata.symbol,
|
220
258
|
address: token.address,
|
@@ -237,6 +275,44 @@ class SwapSDK {
|
|
237
275
|
const data = await response.json();
|
238
276
|
return Number(data.price);
|
239
277
|
}
|
278
|
+
/**
|
279
|
+
* Gets the token balances for a given wallet
|
280
|
+
*
|
281
|
+
* @param params User address and token mints to check
|
282
|
+
* @returns Array of token balances
|
283
|
+
*/
|
284
|
+
async getTokenMintBalance(params) {
|
285
|
+
try {
|
286
|
+
const response = await fetch(`${this.baseUrl}/getMintBalances`, {
|
287
|
+
method: "POST",
|
288
|
+
headers: {
|
289
|
+
"Content-Type": "application/json",
|
290
|
+
},
|
291
|
+
body: JSON.stringify(params),
|
292
|
+
});
|
293
|
+
if (!response.ok) {
|
294
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
295
|
+
}
|
296
|
+
const data = await response.json();
|
297
|
+
return data;
|
298
|
+
}
|
299
|
+
catch (error) {
|
300
|
+
console.error("Error fetching token balances:", error);
|
301
|
+
throw error;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
/**
|
305
|
+
* Health check for the API
|
306
|
+
*
|
307
|
+
* @returns A string "Pong" if the service is operational
|
308
|
+
*/
|
309
|
+
async ping() {
|
310
|
+
const response = await fetch(`${this.baseUrl}/ping`);
|
311
|
+
if (!response.ok) {
|
312
|
+
throw new Error(`API Error: ${response.statusText}`);
|
313
|
+
}
|
314
|
+
return await response.text();
|
315
|
+
}
|
240
316
|
/**
|
241
317
|
* Simulates a transaction.
|
242
318
|
* @param connection The connection to use.
|
@@ -273,7 +349,6 @@ class SwapSDK {
|
|
273
349
|
exports.SwapSDK = SwapSDK;
|
274
350
|
exports.DEX_IDS = {
|
275
351
|
ORCA: "ORCA",
|
276
|
-
// SOLAR_DEX: "SOLAR_DEX",
|
277
352
|
INVARIANT: "INVARIANT",
|
278
353
|
ALL: "ALL",
|
279
354
|
};
|
package/dist/swapSDK.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"swapSDK.js","sourceRoot":"","sources":["../src/swapSDK.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,aAAa;AACb,2DASyB;AACzB,gDAA0B;AAC1B,qCAAiD;
|
1
|
+
{"version":3,"file":"swapSDK.js","sourceRoot":"","sources":["../src/swapSDK.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/swapSDK.ts
CHANGED
@@ -16,16 +16,16 @@ import { handleSimulationError } from "./errors";
|
|
16
16
|
* Parameters to request a swap.
|
17
17
|
*/
|
18
18
|
export interface SwapRequestParams {
|
19
|
-
/** User
|
19
|
+
/** User's public key */
|
20
20
|
publicKey: PublicKey;
|
21
|
-
/** Token A
|
21
|
+
/** Token A's address */
|
22
22
|
tokenA: PublicKey;
|
23
|
-
/** Token B
|
23
|
+
/** Token B's address */
|
24
24
|
tokenB: PublicKey;
|
25
25
|
/** Amount of Token A to swap (in human-readable units) */
|
26
26
|
amountIn: number;
|
27
|
-
/** DEX identifier –
|
28
|
-
dexId:
|
27
|
+
/** DEX identifier – "INVARIANT", "ORCA", or "ALL" */
|
28
|
+
dexId: DexIdTypes;
|
29
29
|
/**
|
30
30
|
* This is used to set options like limit the swap to just two hops to
|
31
31
|
* prevent errors like TooManyAccountLocks
|
@@ -36,36 +36,38 @@ export interface SwapRequestParams {
|
|
36
36
|
export interface RouteOptions {
|
37
37
|
reduceToTwoHops: boolean;
|
38
38
|
}
|
39
|
+
|
39
40
|
export type GetTokenMintBalanceType = {
|
40
41
|
mint: string;
|
41
42
|
balanceUiAmount: number;
|
42
43
|
};
|
44
|
+
|
43
45
|
/**
|
44
46
|
* Result from the swapTx method.
|
45
47
|
*/
|
46
48
|
export interface SwapTxResult {
|
47
|
-
/**
|
49
|
+
/** Fully constructed VersionedTransaction ready for signing */
|
48
50
|
transaction: VersionedTransaction;
|
49
|
-
/**
|
51
|
+
/** Raw transaction data in base64 encoding */
|
52
|
+
serializedTransactions: string;
|
53
|
+
/** Output amount in token decimals */
|
50
54
|
amountOut: number;
|
51
|
-
/**
|
55
|
+
/** Human-readable output amount */
|
52
56
|
amountOutUi: number;
|
53
|
-
/**
|
54
|
-
|
57
|
+
/** Price of Token A in terms of Token B */
|
58
|
+
pairPrice: number;
|
59
|
+
/** Swap route details */
|
60
|
+
routePlan: Array<{
|
55
61
|
tokenA: PublicKey;
|
56
62
|
tokenB: PublicKey;
|
57
|
-
dexId:
|
58
|
-
}
|
59
|
-
/**
|
63
|
+
dexId: DexIdTypes;
|
64
|
+
}>;
|
65
|
+
/** Associated lookup accounts */
|
60
66
|
lookupAccounts: PublicKey[];
|
61
|
-
/**
|
67
|
+
/** Required transaction signers */
|
62
68
|
signers: Keypair[];
|
63
|
-
/**
|
64
|
-
pairPrice: number;
|
65
|
-
|
69
|
+
/** Protocol fee percentage */
|
66
70
|
feeRate: number;
|
67
|
-
|
68
|
-
serializedTransactions: string;
|
69
71
|
}
|
70
72
|
|
71
73
|
/**
|
@@ -102,6 +104,25 @@ export interface SwapIxResult {
|
|
102
104
|
signers: string[];
|
103
105
|
}
|
104
106
|
|
107
|
+
/**
|
108
|
+
* Response from the quote endpoint
|
109
|
+
*/
|
110
|
+
export interface QuoteResponse {
|
111
|
+
tokenA: string;
|
112
|
+
tokenB: string;
|
113
|
+
amountIn: string;
|
114
|
+
amountOut: string;
|
115
|
+
tokenPrice: string;
|
116
|
+
priceImpact: string;
|
117
|
+
feeRate: string;
|
118
|
+
routePlan: Array<{
|
119
|
+
tokenA: string;
|
120
|
+
tokenB: string;
|
121
|
+
dexId: DexIdTypes;
|
122
|
+
}>;
|
123
|
+
dexId: DexIdTypes;
|
124
|
+
}
|
125
|
+
|
105
126
|
/**
|
106
127
|
* Token details returned from the /tokenList endpoint.
|
107
128
|
*/
|
@@ -116,60 +137,99 @@ export interface Token {
|
|
116
137
|
}
|
117
138
|
|
118
139
|
/**
|
119
|
-
*
|
140
|
+
* Balance Check Parameters
|
141
|
+
*/
|
142
|
+
export interface BalanceCheckParams {
|
143
|
+
/** User's wallet address in base58 */
|
144
|
+
userAddress: string;
|
145
|
+
/** Token mint addresses to check */
|
146
|
+
tokenMints: string[];
|
147
|
+
}
|
148
|
+
|
149
|
+
/**
|
150
|
+
* SwapSDK simplifies interaction with the decentralized exchange API, handling swaps, token data, and balance checks.
|
151
|
+
*
|
152
|
+
* Key Features:
|
153
|
+
* - Get swap quotes to preview expected outcomes
|
154
|
+
* - Build swap transactions with automatic route finding
|
155
|
+
* - Get underlying swap instructions for custom transaction handling
|
156
|
+
* - Retrieve token list and price data
|
157
|
+
* - Check token balances
|
158
|
+
* - Transaction simulation
|
120
159
|
*
|
121
160
|
* Usage:
|
122
161
|
* ```ts
|
123
|
-
* import { SwapSDK } from "./SwapSDK";
|
124
|
-
* import { PublicKey } from "@solana/web3.js";
|
162
|
+
* import { SwapSDK, DEX_IDS } from "./SwapSDK";
|
163
|
+
* import { PublicKey, Connection } from "@solana/web3.js";
|
125
164
|
*
|
126
|
-
* const sdk = new SwapSDK(
|
165
|
+
* const sdk = new SwapSDK(); // Uses default production URL
|
166
|
+
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
127
167
|
*
|
128
|
-
* async function
|
129
|
-
*
|
130
|
-
*
|
168
|
+
* async function fullSwapFlow() {
|
169
|
+
* // Example swap parameters
|
170
|
+
* const swapParams = {
|
171
|
+
* publicKey: new PublicKey("UserPublicKeyBase58"),
|
131
172
|
* tokenA: new PublicKey("GU7NS9xCwgNPiAdJ69iusFrRfawjDDPjeMBovhV1d4kn"),
|
132
173
|
* tokenB: new PublicKey("CEBP3CqAbW4zdZA57H2wfaSG1QNdzQ72GiQEbQXyW9Tm"),
|
133
174
|
* amountIn: 10.0,
|
134
|
-
* dexId:
|
175
|
+
* dexId: DEX_IDS.INVARIANT,
|
176
|
+
* options: { reduceToTwoHops: false }
|
135
177
|
* };
|
136
178
|
*
|
137
|
-
* //
|
138
|
-
* const
|
139
|
-
* console.log("
|
179
|
+
* // Get a quote first to see expected outcome
|
180
|
+
* const quote = await sdk.getSwapQuote(swapParams);
|
181
|
+
* console.log("Expected output amount:", quote.amountOut);
|
182
|
+
* console.log("Price impact:", quote.priceImpact);
|
183
|
+
*
|
184
|
+
* // Get complete swap transaction
|
185
|
+
* const txResult = await sdk.swapTx({
|
186
|
+
* ...swapParams,
|
187
|
+
* quote: quote
|
188
|
+
* });
|
189
|
+
* console.log("Serialized Transaction:", txResult.serializedTransactions);
|
140
190
|
*
|
141
|
-
* //
|
142
|
-
* const
|
143
|
-
* console.log("
|
191
|
+
* // Simulate transaction before sending
|
192
|
+
* const simulation = await sdk.simulateTransaction(connection, txResult.transaction);
|
193
|
+
* console.log("Simulation Result:", simulation);
|
144
194
|
*
|
145
|
-
* //
|
195
|
+
* // Get token list
|
146
196
|
* const tokens = await sdk.tokenList();
|
147
|
-
* console.log("Tokens:", tokens);
|
197
|
+
* console.log("Available Tokens:", tokens);
|
148
198
|
*
|
149
|
-
* //
|
150
|
-
* const
|
151
|
-
*
|
199
|
+
* // Check balances
|
200
|
+
* const balances = await sdk.getTokenMintBalance({
|
201
|
+
* userAddress: swapParams.publicKey.toBase58(),
|
202
|
+
* tokenMints: [swapParams.tokenA.toBase58(), swapParams.tokenB.toBase58()]
|
203
|
+
* });
|
204
|
+
* console.log("User Balances:", balances);
|
205
|
+
*
|
206
|
+
* // Get token price
|
207
|
+
* const solPrice = await sdk.tokenPrice("So11111111111111111111111111111111111111112");
|
208
|
+
* console.log("SOL Price:", solPrice);
|
152
209
|
* }
|
153
210
|
*
|
154
|
-
*
|
211
|
+
* fullSwapFlow();
|
155
212
|
* ```
|
156
213
|
*/
|
157
214
|
export class SwapSDK {
|
158
215
|
private baseUrl: string;
|
216
|
+
|
159
217
|
constructor(baseUrl?: string) {
|
160
218
|
this.baseUrl = baseUrl || BASE_URL;
|
161
219
|
}
|
162
220
|
|
221
|
+
base58 = base58;
|
222
|
+
web3 = web3;
|
223
|
+
DEX_IDS = DEX_IDS;
|
224
|
+
|
163
225
|
/**
|
164
|
-
*
|
226
|
+
* Gets a swap quote without executing the swap
|
165
227
|
*
|
166
|
-
* @param params Swap parameters
|
167
|
-
* @returns
|
228
|
+
* @param params Swap parameters
|
229
|
+
* @returns Quote information including expected output amount and price impact
|
168
230
|
*/
|
169
|
-
|
170
|
-
// Prepare the payload by converting PublicKeys to base58 strings
|
231
|
+
async getSwapQuote(params: SwapRequestParams): Promise<QuoteResponse> {
|
171
232
|
const body = {
|
172
|
-
publicKey: params.publicKey.toBase58(),
|
173
233
|
tokenA: params.tokenA.toBase58(),
|
174
234
|
tokenB: params.tokenB.toBase58(),
|
175
235
|
amountIn: params.amountIn.toString(),
|
@@ -177,7 +237,7 @@ export class SwapSDK {
|
|
177
237
|
options: params.options,
|
178
238
|
};
|
179
239
|
|
180
|
-
const response = await fetch(`${this.baseUrl}/
|
240
|
+
const response = await fetch(`${this.baseUrl}/quote`, {
|
181
241
|
method: "POST",
|
182
242
|
headers: {
|
183
243
|
"Content-Type": "application/json",
|
@@ -189,21 +249,55 @@ export class SwapSDK {
|
|
189
249
|
throw new Error(`API Error: ${response.statusText}`);
|
190
250
|
}
|
191
251
|
|
192
|
-
return response.json();
|
252
|
+
return await response.json();
|
193
253
|
}
|
194
254
|
|
195
|
-
|
196
|
-
|
197
|
-
|
255
|
+
/**
|
256
|
+
* Executes a swap based on a previously obtained quote
|
257
|
+
*
|
258
|
+
* @param params Swap parameters including the quote
|
259
|
+
* @returns Transaction and output details
|
260
|
+
*/
|
261
|
+
async executeSwap(params: {
|
262
|
+
publicKey: PublicKey;
|
263
|
+
quote: QuoteResponse;
|
264
|
+
}): Promise<any> {
|
265
|
+
const body = {
|
266
|
+
publicKey: params.publicKey.toBase58(),
|
267
|
+
quote: params.quote,
|
268
|
+
};
|
269
|
+
|
270
|
+
const response = await fetch(`${this.baseUrl}/swap`, {
|
271
|
+
method: "POST",
|
272
|
+
headers: {
|
273
|
+
"Content-Type": "application/json",
|
274
|
+
},
|
275
|
+
body: JSON.stringify(body),
|
276
|
+
});
|
277
|
+
|
278
|
+
if (!response.ok) {
|
279
|
+
throw new Error(`API Error: ${response.statusText}`);
|
280
|
+
}
|
281
|
+
|
282
|
+
return await response.json();
|
283
|
+
}
|
198
284
|
|
199
285
|
/**
|
200
286
|
* Calls the swap endpoint and returns a fully constructed Transaction.
|
287
|
+
* This method is a wrapper that gets a quote first, then executes the swap.
|
201
288
|
*
|
202
289
|
* @param params Swap parameters.
|
203
290
|
* @returns A promise that resolves to a SwapTxResult.
|
204
291
|
*/
|
205
292
|
async swapTx(params: SwapRequestParams): Promise<SwapTxResult> {
|
206
|
-
|
293
|
+
// First get a quote
|
294
|
+
const quote = await this.getSwapQuote(params);
|
295
|
+
|
296
|
+
// Then execute the swap with the quote
|
297
|
+
const data = await this.executeSwap({
|
298
|
+
publicKey: params.publicKey,
|
299
|
+
quote,
|
300
|
+
});
|
207
301
|
|
208
302
|
// Convert the base64-encoded transaction into a VersionedTransaction.
|
209
303
|
const txBuffer = Buffer.from(data.transaction, "base64");
|
@@ -215,38 +309,48 @@ export class SwapSDK {
|
|
215
309
|
);
|
216
310
|
|
217
311
|
// Convert the route plan tokens into PublicKey objects.
|
218
|
-
const routePlan = (
|
312
|
+
const routePlan = (quote.routePlan || []).map((rp: any) => ({
|
219
313
|
tokenA: new PublicKey(rp.tokenA),
|
220
314
|
tokenB: new PublicKey(rp.tokenB),
|
221
|
-
dexId: rp.dexId,
|
315
|
+
dexId: rp.dexId as DexIdTypes,
|
222
316
|
}));
|
223
317
|
|
224
|
-
// Convert each
|
318
|
+
// Convert each base58-encoded signer secret into a Keypair.
|
225
319
|
const signers = data.signers.map((s: string) =>
|
226
320
|
Keypair.fromSecretKey(base58.decode(s))
|
227
321
|
);
|
322
|
+
|
228
323
|
transaction.sign(signers);
|
324
|
+
|
229
325
|
return {
|
230
326
|
transaction,
|
231
327
|
serializedTransactions: data.transaction,
|
232
328
|
amountOut: Number(data.amountOut),
|
233
|
-
amountOutUi: Number(
|
234
|
-
pairPrice:
|
329
|
+
amountOutUi: Number(quote.amountOut),
|
330
|
+
pairPrice: Number(quote.tokenPrice),
|
235
331
|
routePlan,
|
236
332
|
lookupAccounts,
|
237
333
|
signers,
|
238
|
-
feeRate: parseFloat(
|
334
|
+
feeRate: parseFloat(quote.feeRate),
|
239
335
|
};
|
240
336
|
}
|
241
337
|
|
242
338
|
/**
|
243
339
|
* Calls the swap endpoint and returns the raw instructions and related data.
|
340
|
+
* This method is a wrapper that gets a quote first, then executes the swap to get instructions.
|
244
341
|
*
|
245
342
|
* @param params Swap parameters.
|
246
343
|
* @returns A promise that resolves to a SwapIxResult.
|
247
344
|
*/
|
248
345
|
async swapIx(params: SwapRequestParams): Promise<SwapIxResult> {
|
249
|
-
|
346
|
+
// First get a quote
|
347
|
+
const quote = await this.getSwapQuote(params);
|
348
|
+
|
349
|
+
// Then execute the swap with the quote
|
350
|
+
const data = await this.executeSwap({
|
351
|
+
publicKey: params.publicKey,
|
352
|
+
quote,
|
353
|
+
});
|
250
354
|
|
251
355
|
// Convert lookup accounts from strings to PublicKey objects.
|
252
356
|
const lookupAccounts: PublicKey[] = (data.lookUpAccounts || []).map(
|
@@ -254,7 +358,7 @@ export class SwapSDK {
|
|
254
358
|
);
|
255
359
|
|
256
360
|
// Convert the route plan tokens into PublicKey objects.
|
257
|
-
const routePlan = (
|
361
|
+
const routePlan = (quote.routePlan || []).map((rp: any) => ({
|
258
362
|
tokenA: new PublicKey(rp.tokenA),
|
259
363
|
tokenB: new PublicKey(rp.tokenB),
|
260
364
|
dexId: rp.dexId,
|
@@ -276,7 +380,7 @@ export class SwapSDK {
|
|
276
380
|
return {
|
277
381
|
instructionGroups,
|
278
382
|
amountOut: Number(data.amountOut),
|
279
|
-
amountOutUi: Number(
|
383
|
+
amountOutUi: Number(quote.amountOut),
|
280
384
|
routePlan,
|
281
385
|
lookupAccounts,
|
282
386
|
signers: data.signers,
|
@@ -294,7 +398,7 @@ export class SwapSDK {
|
|
294
398
|
throw new Error(`API Error: ${response.statusText}`);
|
295
399
|
}
|
296
400
|
const data = await response.json();
|
297
|
-
return data.
|
401
|
+
return data.map((token: any) => ({
|
298
402
|
name: token.metadata.name,
|
299
403
|
symbol: token.metadata.symbol,
|
300
404
|
address: token.address,
|
@@ -319,31 +423,49 @@ export class SwapSDK {
|
|
319
423
|
return Number(data.price);
|
320
424
|
}
|
321
425
|
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
426
|
+
/**
|
427
|
+
* Gets the token balances for a given wallet
|
428
|
+
*
|
429
|
+
* @param params User address and token mints to check
|
430
|
+
* @returns Array of token balances
|
431
|
+
*/
|
432
|
+
async getTokenMintBalance(
|
433
|
+
params: BalanceCheckParams
|
434
|
+
): Promise<GetTokenMintBalanceType[]> {
|
330
435
|
try {
|
331
436
|
const response = await fetch(`${this.baseUrl}/getMintBalances`, {
|
332
437
|
method: "POST",
|
333
438
|
headers: {
|
334
439
|
"Content-Type": "application/json",
|
335
440
|
},
|
336
|
-
body: JSON.stringify(
|
441
|
+
body: JSON.stringify(params),
|
337
442
|
});
|
443
|
+
|
338
444
|
if (!response.ok) {
|
339
445
|
throw new Error(`HTTP error! status: ${response.status}`);
|
340
446
|
}
|
447
|
+
|
341
448
|
const data = await response.json();
|
342
449
|
return data as GetTokenMintBalanceType[];
|
343
450
|
} catch (error) {
|
344
|
-
console.
|
451
|
+
console.error("Error fetching token balances:", error);
|
452
|
+
throw error;
|
345
453
|
}
|
346
|
-
}
|
454
|
+
}
|
455
|
+
|
456
|
+
/**
|
457
|
+
* Health check for the API
|
458
|
+
*
|
459
|
+
* @returns A string "Pong" if the service is operational
|
460
|
+
*/
|
461
|
+
async ping(): Promise<string> {
|
462
|
+
const response = await fetch(`${this.baseUrl}/ping`);
|
463
|
+
if (!response.ok) {
|
464
|
+
throw new Error(`API Error: ${response.statusText}`);
|
465
|
+
}
|
466
|
+
return await response.text();
|
467
|
+
}
|
468
|
+
|
347
469
|
/**
|
348
470
|
* Simulates a transaction.
|
349
471
|
* @param connection The connection to use.
|
@@ -384,7 +506,6 @@ export class SwapSDK {
|
|
384
506
|
|
385
507
|
export const DEX_IDS = {
|
386
508
|
ORCA: "ORCA",
|
387
|
-
// SOLAR_DEX: "SOLAR_DEX",
|
388
509
|
INVARIANT: "INVARIANT",
|
389
510
|
ALL: "ALL",
|
390
511
|
} as const;
|