@velocity-exchange/sdk 0.8.0 → 0.10.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/lib/browser/adminClient.d.ts +13 -10
- package/lib/browser/adminClient.js +16 -21
- package/lib/browser/decode/user.js +3 -1
- package/lib/browser/equityFloorManager.d.ts +154 -0
- package/lib/browser/equityFloorManager.js +283 -0
- package/lib/browser/idl/velocity.d.ts +85 -10
- package/lib/browser/idl/velocity.json +85 -10
- package/lib/browser/index.d.ts +4 -0
- package/lib/browser/index.js +5 -0
- package/lib/browser/jupiter/jupiterClient.d.ts +31 -27
- package/lib/browser/jupiter/jupiterClient.js +84 -37
- package/lib/browser/math/margin.d.ts +28 -0
- package/lib/browser/math/margin.js +43 -1
- package/lib/browser/math/superStake.d.ts +9 -9
- package/lib/browser/math/superStake.js +8 -8
- package/lib/browser/swap/UnifiedSwapClient.d.ts +38 -76
- package/lib/browser/swap/UnifiedSwapClient.js +53 -110
- package/lib/browser/swap/routeInstructions.d.ts +19 -0
- package/lib/browser/swap/routeInstructions.js +43 -0
- package/lib/browser/swap/types.d.ts +196 -0
- package/lib/browser/swap/types.js +88 -0
- package/lib/browser/titan/titanClient.d.ts +37 -67
- package/lib/browser/titan/titanClient.js +160 -103
- package/lib/browser/types.d.ts +6 -2
- package/lib/browser/types.js +2 -0
- package/lib/browser/user.d.ts +43 -18
- package/lib/browser/user.js +94 -45
- package/lib/browser/velocityClient.d.ts +86 -103
- package/lib/browser/velocityClient.js +157 -298
- package/lib/node/adminClient.d.ts +13 -10
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +16 -21
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +3 -1
- package/lib/node/equityFloorManager.d.ts +155 -0
- package/lib/node/equityFloorManager.d.ts.map +1 -0
- package/lib/node/equityFloorManager.js +283 -0
- package/lib/node/idl/velocity.d.ts +85 -10
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +85 -10
- package/lib/node/index.d.ts +4 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +5 -0
- package/lib/node/jupiter/jupiterClient.d.ts +31 -27
- package/lib/node/jupiter/jupiterClient.d.ts.map +1 -1
- package/lib/node/jupiter/jupiterClient.js +84 -37
- package/lib/node/math/margin.d.ts +28 -0
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/math/margin.js +43 -1
- package/lib/node/math/superStake.d.ts +9 -9
- package/lib/node/math/superStake.d.ts.map +1 -1
- package/lib/node/math/superStake.js +8 -8
- package/lib/node/swap/UnifiedSwapClient.d.ts +38 -76
- package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.js +53 -110
- package/lib/node/swap/routeInstructions.d.ts +20 -0
- package/lib/node/swap/routeInstructions.d.ts.map +1 -0
- package/lib/node/swap/routeInstructions.js +43 -0
- package/lib/node/swap/types.d.ts +197 -0
- package/lib/node/swap/types.d.ts.map +1 -0
- package/lib/node/swap/types.js +88 -0
- package/lib/node/titan/titanClient.d.ts +37 -67
- package/lib/node/titan/titanClient.d.ts.map +1 -1
- package/lib/node/titan/titanClient.js +160 -103
- package/lib/node/types.d.ts +6 -2
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/types.js +2 -0
- package/lib/node/user.d.ts +43 -18
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +94 -45
- package/lib/node/velocityClient.d.ts +86 -103
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +157 -298
- package/package.json +1 -1
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { AddressLookupTableAccount, PublicKey, TransactionInstruction, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import { BN } from '../isomorphic/anchor';
|
|
3
|
+
export type SwapMode = 'ExactIn' | 'ExactOut';
|
|
4
|
+
export type SwapClientType = 'jupiter' | 'titan';
|
|
5
|
+
/** Account budget assumed when a caller doesn't specify one. */
|
|
6
|
+
export declare const DEFAULT_SWAP_MAX_ACCOUNTS = 50;
|
|
7
|
+
/**
|
|
8
|
+
* Quote fields shared by every provider. Provider-specific extras are optional
|
|
9
|
+
* and must never be required to build a swap — see {@link SwapQuote}.
|
|
10
|
+
*/
|
|
11
|
+
export interface UnifiedQuoteResponse {
|
|
12
|
+
inputMint: string;
|
|
13
|
+
inAmount: string;
|
|
14
|
+
outputMint: string;
|
|
15
|
+
outAmount: string;
|
|
16
|
+
swapMode: SwapMode;
|
|
17
|
+
/**
|
|
18
|
+
* The slippage the route was quoted at. Authoritative — this is what the
|
|
19
|
+
* swap executes with, since {@link SwapProvider.getRouteInstructions} takes
|
|
20
|
+
* no slippage override. To swap at different slippage, quote again.
|
|
21
|
+
*/
|
|
22
|
+
slippageBps: number;
|
|
23
|
+
routePlan: Array<{
|
|
24
|
+
swapInfo: any;
|
|
25
|
+
percent: number;
|
|
26
|
+
}>;
|
|
27
|
+
/** Jupiter only. */
|
|
28
|
+
otherAmountThreshold?: string;
|
|
29
|
+
/** Jupiter provides this; Titan doesn't, so callers derive it. */
|
|
30
|
+
priceImpactPct?: string;
|
|
31
|
+
platformFee?: {
|
|
32
|
+
amount?: string;
|
|
33
|
+
feeBps?: number;
|
|
34
|
+
};
|
|
35
|
+
contextSlot?: number;
|
|
36
|
+
timeTaken?: number;
|
|
37
|
+
error?: string;
|
|
38
|
+
errorCode?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* What the provider says its route does, recorded when the quote was produced.
|
|
42
|
+
*
|
|
43
|
+
* An implementation detail of the tamper check described on
|
|
44
|
+
* {@link expectProviderRoute} — you never write one of these. {@link
|
|
45
|
+
* buildSwapQuote} records it from the quote a provider is already returning.
|
|
46
|
+
*/
|
|
47
|
+
export interface SwapRouteFields {
|
|
48
|
+
readonly inputMint: string;
|
|
49
|
+
readonly outputMint: string;
|
|
50
|
+
readonly inAmount: string;
|
|
51
|
+
readonly outAmount: string;
|
|
52
|
+
readonly swapMode: SwapMode;
|
|
53
|
+
readonly slippageBps: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Everything a provider needs to turn its own quote back into instructions.
|
|
57
|
+
*
|
|
58
|
+
* Attached to the quote rather than held on the client so that building a swap
|
|
59
|
+
* is a pure function of the quote you were given. A provider that kept this
|
|
60
|
+
* internally would silently build against whatever route it happened to have
|
|
61
|
+
* cached, which is invisible at the call site and wrong whenever more than one
|
|
62
|
+
* quote is in flight.
|
|
63
|
+
*
|
|
64
|
+
* Opaque — read the normalized fields on {@link SwapQuote} instead.
|
|
65
|
+
*/
|
|
66
|
+
export type SwapProviderRoute = {
|
|
67
|
+
readonly provider: 'jupiter';
|
|
68
|
+
readonly quote: unknown;
|
|
69
|
+
readonly routed: SwapRouteFields;
|
|
70
|
+
readonly quotedFor?: string;
|
|
71
|
+
} | {
|
|
72
|
+
readonly provider: 'titan';
|
|
73
|
+
readonly route: unknown;
|
|
74
|
+
readonly routed: SwapRouteFields;
|
|
75
|
+
readonly quotedFor?: string;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* A {@link SwapProviderRoute} as a provider hands it to {@link buildSwapQuote} —
|
|
79
|
+
* the payload without the `routed` fields, which `buildSwapQuote` records itself.
|
|
80
|
+
*/
|
|
81
|
+
export type SwapProviderRoutePayload = OmitRouted<SwapProviderRoute>;
|
|
82
|
+
/** Distributes over the union, so each member keeps its own payload field. */
|
|
83
|
+
type OmitRouted<R> = R extends unknown ? Omit<R, 'routed'> : never;
|
|
84
|
+
/**
|
|
85
|
+
* A quote plus the provider payload needed to execute it. Always pass the quote
|
|
86
|
+
* you intend to swap on; providers will not fall back to a previous one.
|
|
87
|
+
*
|
|
88
|
+
* Treat it as immutable. The normalized fields are checked against the payload
|
|
89
|
+
* before a swap is built, so an edited copy is rejected rather than silently
|
|
90
|
+
* executed as the swap it was originally quoted for — re-quote instead.
|
|
91
|
+
*/
|
|
92
|
+
export type SwapQuote = UnifiedQuoteResponse & {
|
|
93
|
+
readonly providerRoute: SwapProviderRoute;
|
|
94
|
+
};
|
|
95
|
+
export interface SwapQuoteParams {
|
|
96
|
+
inputMint: PublicKey;
|
|
97
|
+
outputMint: PublicKey;
|
|
98
|
+
amount: BN;
|
|
99
|
+
/** Required by Titan, which bakes the user's token accounts into the route. */
|
|
100
|
+
userPublicKey?: PublicKey;
|
|
101
|
+
maxAccounts?: number;
|
|
102
|
+
slippageBps?: number;
|
|
103
|
+
swapMode?: SwapMode;
|
|
104
|
+
onlyDirectRoutes?: boolean;
|
|
105
|
+
excludeDexes?: string[];
|
|
106
|
+
/** Titan only. */
|
|
107
|
+
sizeConstraint?: number;
|
|
108
|
+
/** Titan only. */
|
|
109
|
+
accountsLimitWritable?: number;
|
|
110
|
+
/** Jupiter only. */
|
|
111
|
+
autoSlippage?: boolean;
|
|
112
|
+
/** Jupiter only. */
|
|
113
|
+
maxAutoSlippageBps?: number;
|
|
114
|
+
/** Jupiter only. */
|
|
115
|
+
usdEstimate?: number;
|
|
116
|
+
}
|
|
117
|
+
export interface SwapRouteInstructions {
|
|
118
|
+
instructions: TransactionInstruction[];
|
|
119
|
+
lookupTables: AddressLookupTableAccount[];
|
|
120
|
+
}
|
|
121
|
+
export interface GetRouteInstructionsParams {
|
|
122
|
+
quote: SwapQuote;
|
|
123
|
+
/**
|
|
124
|
+
* Wallet the swap executes as. Must be the wallet the quote was requested
|
|
125
|
+
* for when the provider binds routes to a wallet — see
|
|
126
|
+
* {@link expectProviderRoute}.
|
|
127
|
+
*
|
|
128
|
+
* Don't be confused by the Velocity user account public key, which is different.
|
|
129
|
+
* This is usually the Velocity authority.
|
|
130
|
+
*/
|
|
131
|
+
userPublicKey: PublicKey;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The contract every swap provider implements.
|
|
135
|
+
*
|
|
136
|
+
* Quote, then build — either into velocity's swap bracket, or into a standalone
|
|
137
|
+
* transaction. Both clients satisfying the same interface is what stops one
|
|
138
|
+
* provider growing behaviour the other doesn't have; callers get identical
|
|
139
|
+
* semantics regardless of which is configured.
|
|
140
|
+
*
|
|
141
|
+
* Provider-specific request fields live on {@link SwapQuoteParams} and are
|
|
142
|
+
* mapped by the provider itself, so adding one never means editing the unified
|
|
143
|
+
* client. Nothing that only one provider can honour belongs on
|
|
144
|
+
* {@link GetRouteInstructionsParams} — a build-time parameter the other silently
|
|
145
|
+
* ignores is indistinguishable from it being applied.
|
|
146
|
+
*/
|
|
147
|
+
export interface SwapProvider {
|
|
148
|
+
readonly providerName: SwapClientType;
|
|
149
|
+
getQuote(params: SwapQuoteParams): Promise<SwapQuote>;
|
|
150
|
+
/**
|
|
151
|
+
* Builds the route instructions for a quote returned by this provider's
|
|
152
|
+
* `getQuote`, at the slippage that quote was priced at.
|
|
153
|
+
* @throws If the quote came from a different provider or a different wallet.
|
|
154
|
+
*/
|
|
155
|
+
getRouteInstructions(params: GetRouteInstructionsParams): Promise<SwapRouteInstructions>;
|
|
156
|
+
/**
|
|
157
|
+
* Builds a complete, self-contained swap transaction — the setup and
|
|
158
|
+
* teardown `getRouteInstructions` strips are still attached: compute budget,
|
|
159
|
+
* token account creation, and SOL wrapping.
|
|
160
|
+
*
|
|
161
|
+
* For swaps the caller signs and sends on its own. A swap running inside
|
|
162
|
+
* velocity's `beginSwap`/`endSwap` bracket wants `getRouteInstructions`
|
|
163
|
+
* instead — velocity supplies all three itself, and a second copy wraps SOL
|
|
164
|
+
* that nothing then unwraps.
|
|
165
|
+
*
|
|
166
|
+
* @throws If the quote came from a different provider or a different wallet.
|
|
167
|
+
*/
|
|
168
|
+
getSwapTransaction(params: GetRouteInstructionsParams): Promise<VersionedTransaction>;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Assembles the {@link SwapQuote} a provider's `getQuote` returns, from the
|
|
172
|
+
* normalized quote and the route payload that will execute it.
|
|
173
|
+
*
|
|
174
|
+
* Providers call this rather than building the object themselves. It records
|
|
175
|
+
* what the route was quoted with next to the payload, which is what lets
|
|
176
|
+
* {@link expectProviderRoute} reject a quote edited after it was returned — so
|
|
177
|
+
* that check needs no cooperation from the provider beyond calling this.
|
|
178
|
+
*/
|
|
179
|
+
export declare function buildSwapQuote<Q extends UnifiedQuoteResponse>(quote: Q, providerRoute: SwapProviderRoutePayload): Q & SwapQuote;
|
|
180
|
+
/**
|
|
181
|
+
* Narrows a quote's payload to `provider`, checks it can be executed by
|
|
182
|
+
* `userPublicKey`, and checks it still matches the quote it travels on.
|
|
183
|
+
*
|
|
184
|
+
* A route is wallet-bound when the provider resolves the user's token accounts
|
|
185
|
+
* at quote time (Titan does; Jupiter builds per-wallet at swap time). Those
|
|
186
|
+
* providers record the wallet on `quotedFor`, and executing such a route as
|
|
187
|
+
* anyone else moves funds through accounts the signer doesn't own.
|
|
188
|
+
*
|
|
189
|
+
* @throws If the quote was produced by a different provider, for a wallet other
|
|
190
|
+
* than `userPublicKey`, or for a different pair, size, mode or slippage than the
|
|
191
|
+
* quote now claims.
|
|
192
|
+
*/
|
|
193
|
+
export declare function expectProviderRoute<T extends SwapClientType>(quote: SwapQuote, provider: T, userPublicKey: PublicKey): Extract<SwapProviderRoute, {
|
|
194
|
+
provider: T;
|
|
195
|
+
}>;
|
|
196
|
+
export {};
|
|
197
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/swap/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.expectProviderRoute = exports.buildSwapQuote = exports.DEFAULT_SWAP_MAX_ACCOUNTS = void 0;
|
|
4
|
+
/** Account budget assumed when a caller doesn't specify one. */
|
|
5
|
+
exports.DEFAULT_SWAP_MAX_ACCOUNTS = 50;
|
|
6
|
+
/**
|
|
7
|
+
* Assembles the {@link SwapQuote} a provider's `getQuote` returns, from the
|
|
8
|
+
* normalized quote and the route payload that will execute it.
|
|
9
|
+
*
|
|
10
|
+
* Providers call this rather than building the object themselves. It records
|
|
11
|
+
* what the route was quoted with next to the payload, which is what lets
|
|
12
|
+
* {@link expectProviderRoute} reject a quote edited after it was returned — so
|
|
13
|
+
* that check needs no cooperation from the provider beyond calling this.
|
|
14
|
+
*/
|
|
15
|
+
function buildSwapQuote(quote, providerRoute) {
|
|
16
|
+
const { inputMint, outputMint, inAmount, outAmount, swapMode, slippageBps } = quote;
|
|
17
|
+
const routed = {
|
|
18
|
+
inputMint,
|
|
19
|
+
outputMint,
|
|
20
|
+
inAmount,
|
|
21
|
+
outAmount,
|
|
22
|
+
swapMode,
|
|
23
|
+
slippageBps,
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
...quote,
|
|
27
|
+
providerRoute: { ...providerRoute, routed },
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
exports.buildSwapQuote = buildSwapQuote;
|
|
31
|
+
/** Fields that must describe the same swap on the quote and on its route. */
|
|
32
|
+
const ROUTED_FIELDS = [
|
|
33
|
+
'inputMint',
|
|
34
|
+
'outputMint',
|
|
35
|
+
'inAmount',
|
|
36
|
+
'outAmount',
|
|
37
|
+
'swapMode',
|
|
38
|
+
'slippageBps',
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* Throws unless the quote's normalized fields still describe the route it
|
|
42
|
+
* carries.
|
|
43
|
+
*
|
|
44
|
+
* Callers and velocity's swap guards read the normalized fields; the provider
|
|
45
|
+
* executes the opaque payload. Nothing but this ties the two together, so a
|
|
46
|
+
* quote that was copied and edited — `{ ...quote, inAmount }`, a mint rewritten
|
|
47
|
+
* in place — would pass every pair, size and slippage check and then execute the
|
|
48
|
+
* route it was originally quoted for.
|
|
49
|
+
*/
|
|
50
|
+
function assertQuoteMatchesRoute(quote, provider, routed) {
|
|
51
|
+
if (!routed) {
|
|
52
|
+
throw new Error(`Quote is missing the route fields recorded at quote time. It must come from ${provider}'s getQuote, which builds it with buildSwapQuote.`);
|
|
53
|
+
}
|
|
54
|
+
for (const field of ROUTED_FIELDS) {
|
|
55
|
+
// Stringified: a provider may normalize a numeric field it decoded.
|
|
56
|
+
if (String(quote[field]) !== String(routed[field])) {
|
|
57
|
+
throw new Error(`Quote reports ${field} ${String(quote[field])} but the route it carries was quoted with ${String(routed[field])}. The quote was modified after it was returned; re-quote instead.`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Narrows a quote's payload to `provider`, checks it can be executed by
|
|
63
|
+
* `userPublicKey`, and checks it still matches the quote it travels on.
|
|
64
|
+
*
|
|
65
|
+
* A route is wallet-bound when the provider resolves the user's token accounts
|
|
66
|
+
* at quote time (Titan does; Jupiter builds per-wallet at swap time). Those
|
|
67
|
+
* providers record the wallet on `quotedFor`, and executing such a route as
|
|
68
|
+
* anyone else moves funds through accounts the signer doesn't own.
|
|
69
|
+
*
|
|
70
|
+
* @throws If the quote was produced by a different provider, for a wallet other
|
|
71
|
+
* than `userPublicKey`, or for a different pair, size, mode or slippage than the
|
|
72
|
+
* quote now claims.
|
|
73
|
+
*/
|
|
74
|
+
function expectProviderRoute(quote, provider, userPublicKey) {
|
|
75
|
+
const route = quote === null || quote === void 0 ? void 0 : quote.providerRoute;
|
|
76
|
+
if (!route) {
|
|
77
|
+
throw new Error(`Quote is missing its provider route. It must come from ${provider}'s getQuote.`);
|
|
78
|
+
}
|
|
79
|
+
if (route.provider !== provider) {
|
|
80
|
+
throw new Error(`Quote came from ${route.provider} but is being swapped on ${provider}.`);
|
|
81
|
+
}
|
|
82
|
+
if (route.quotedFor && route.quotedFor !== userPublicKey.toString()) {
|
|
83
|
+
throw new Error(`Quote was requested for ${route.quotedFor} but is being swapped by ${userPublicKey.toString()}.`);
|
|
84
|
+
}
|
|
85
|
+
assertQuoteMatchesRoute(quote, provider, route.routed);
|
|
86
|
+
return route;
|
|
87
|
+
}
|
|
88
|
+
exports.expectProviderRoute = expectProviderRoute;
|
|
@@ -1,36 +1,16 @@
|
|
|
1
|
-
import { Connection,
|
|
2
|
-
import {
|
|
1
|
+
import { Connection, AddressLookupTableAccount, VersionedTransaction } from '@solana/web3.js';
|
|
2
|
+
import { GetRouteInstructionsParams, SwapProvider, SwapQuote, SwapQuoteParams, SwapRouteInstructions } from '../swap/types';
|
|
3
3
|
export declare enum SwapMode {
|
|
4
4
|
ExactIn = "ExactIn",
|
|
5
5
|
ExactOut = "ExactOut"
|
|
6
6
|
}
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
inAmount: string;
|
|
10
|
-
outputMint: string;
|
|
11
|
-
outAmount: string;
|
|
12
|
-
swapMode: SwapMode;
|
|
13
|
-
slippageBps: number;
|
|
14
|
-
platformFee?: {
|
|
15
|
-
amount?: string;
|
|
16
|
-
feeBps?: number;
|
|
17
|
-
};
|
|
18
|
-
routePlan: Array<{
|
|
19
|
-
swapInfo: any;
|
|
20
|
-
percent: number;
|
|
21
|
-
}>;
|
|
22
|
-
contextSlot?: number;
|
|
23
|
-
timeTaken?: number;
|
|
24
|
-
error?: string;
|
|
25
|
-
errorCode?: string;
|
|
26
|
-
}
|
|
27
|
-
export declare class TitanClient {
|
|
7
|
+
export declare class TitanClient implements SwapProvider {
|
|
8
|
+
readonly providerName = "titan";
|
|
28
9
|
authToken: string;
|
|
29
10
|
url: string;
|
|
30
11
|
connection: Connection;
|
|
31
12
|
proxyUrl?: string;
|
|
32
|
-
|
|
33
|
-
private lastQuoteParams?;
|
|
13
|
+
lookupTableCache: Map<string, AddressLookupTableAccount>;
|
|
34
14
|
constructor({ connection, authToken, url, proxyUrl, }: {
|
|
35
15
|
connection: Connection;
|
|
36
16
|
authToken: string;
|
|
@@ -39,52 +19,42 @@ export declare class TitanClient {
|
|
|
39
19
|
});
|
|
40
20
|
private buildParams;
|
|
41
21
|
/**
|
|
42
|
-
* Get
|
|
22
|
+
* Get the best available route for a swap.
|
|
23
|
+
*
|
|
24
|
+
* The route is returned on the quote's `providerRoute`, so
|
|
25
|
+
* {@link getRouteInstructions} builds exactly what was quoted here, at the
|
|
26
|
+
* slippage quoted here.
|
|
27
|
+
* @throws If `userPublicKey` is missing — Titan bakes the user's token
|
|
28
|
+
* accounts into the route, so a route quoted for one wallet cannot be
|
|
29
|
+
* executed by another. The wallet is recorded on the route and enforced
|
|
30
|
+
* when the route is built.
|
|
31
|
+
*/
|
|
32
|
+
getQuote({ inputMint, outputMint, amount, userPublicKey, maxAccounts, slippageBps, swapMode, onlyDirectRoutes, excludeDexes, sizeConstraint, accountsLimitWritable, }: SwapQuoteParams): Promise<SwapQuote>;
|
|
33
|
+
/**
|
|
34
|
+
* The route as Titan built it, compiled into a signable transaction. Titan
|
|
35
|
+
* returns instructions rather than a transaction, so unlike Jupiter there is
|
|
36
|
+
* nothing to strip — the route already includes its own setup and teardown.
|
|
37
|
+
* @throws If the quote came from a different provider or a different wallet,
|
|
38
|
+
* or if a lookup table the route depends on can't be loaded.
|
|
43
39
|
*/
|
|
44
|
-
|
|
45
|
-
slippageBps, swapMode, onlyDirectRoutes, excludeDexes, sizeConstraint, accountsLimitWritable, }: {
|
|
46
|
-
inputMint: PublicKey;
|
|
47
|
-
outputMint: PublicKey;
|
|
48
|
-
amount: BN;
|
|
49
|
-
userPublicKey: PublicKey;
|
|
50
|
-
maxAccounts?: number;
|
|
51
|
-
slippageBps?: number;
|
|
52
|
-
swapMode?: string;
|
|
53
|
-
onlyDirectRoutes?: boolean;
|
|
54
|
-
excludeDexes?: string[];
|
|
55
|
-
sizeConstraint?: number;
|
|
56
|
-
accountsLimitWritable?: number;
|
|
57
|
-
}): Promise<QuoteResponse>;
|
|
40
|
+
getSwapTransaction({ quote, userPublicKey, }: GetRouteInstructionsParams): Promise<VersionedTransaction>;
|
|
58
41
|
/**
|
|
59
|
-
*
|
|
42
|
+
* Builds the route instructions for a quote returned by {@link getQuote}.
|
|
43
|
+
*
|
|
44
|
+
* The route travels on the quote, so this reads no client state and two
|
|
45
|
+
* quotes in flight can never be confused for one another. Slippage was
|
|
46
|
+
* fixed when Titan built the route, so there is nothing to apply here.
|
|
47
|
+
* @throws If the quote came from a different provider or a different wallet,
|
|
48
|
+
* or if a lookup table the route depends on can't be loaded.
|
|
60
49
|
*/
|
|
61
|
-
|
|
62
|
-
inputMint?: PublicKey;
|
|
63
|
-
outputMint?: PublicKey;
|
|
64
|
-
amount?: BN;
|
|
65
|
-
userPublicKey: PublicKey;
|
|
66
|
-
maxAccounts?: number;
|
|
67
|
-
slippageBps?: number;
|
|
68
|
-
swapMode?: SwapMode;
|
|
69
|
-
onlyDirectRoutes?: boolean;
|
|
70
|
-
excludeDexes?: string[];
|
|
71
|
-
sizeConstraint?: number;
|
|
72
|
-
accountsLimitWritable?: number;
|
|
73
|
-
}): Promise<{
|
|
74
|
-
transactionMessage: TransactionMessage;
|
|
75
|
-
lookupTables: AddressLookupTableAccount[];
|
|
76
|
-
}>;
|
|
50
|
+
getRouteInstructions({ quote, userPublicKey, }: GetRouteInstructionsParams): Promise<SwapRouteInstructions>;
|
|
77
51
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* @
|
|
52
|
+
* Fetches a lookup table required by a route, retrying transient RPC
|
|
53
|
+
* failures (rate limiting in particular) before giving up. Checks the
|
|
54
|
+
* instance cache first and populates it on a fresh fetch.
|
|
55
|
+
* @throws If the table still can't be loaded, or doesn't exist on-chain.
|
|
82
56
|
*/
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
inputMint: PublicKey;
|
|
86
|
-
outputMint: PublicKey;
|
|
87
|
-
}): TransactionInstruction[];
|
|
88
|
-
private getTransactionMessageAndLookupTables;
|
|
57
|
+
private fetchLookupTable;
|
|
58
|
+
private getInstructionsAndLookupTables;
|
|
89
59
|
}
|
|
90
60
|
//# sourceMappingURL=titanClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"titanClient.d.ts","sourceRoot":"","sources":["../../../src/titan/titanClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,
|
|
1
|
+
{"version":3,"file":"titanClient.d.ts","sourceRoot":"","sources":["../../../src/titan/titanClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EAEV,yBAAyB,EAGzB,oBAAoB,EACpB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EAEN,0BAA0B,EAC1B,YAAY,EACZ,SAAS,EACT,eAAe,EACf,qBAAqB,EAGrB,MAAM,eAAe,CAAC;AAEvB,oBAAY,QAAQ;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACrB;AA4FD,qBAAa,WAAY,YAAW,YAAY;IAC/C,SAAgB,YAAY,WAAW;IAEvC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,yCAAgD;gBAEpD,EACX,UAAU,EACV,SAAS,EACT,GAAG,EACH,QAAQ,GACR,EAAE;QACF,UAAU,EAAE,UAAU,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KAClB;IAOD,OAAO,CAAC,WAAW;IAwDnB;;;;;;;;;;OAUG;IACU,QAAQ,CAAC,EACrB,SAAS,EACT,UAAU,EACV,MAAM,EACN,aAAa,EACb,WAAuC,EACvC,WAAW,EACX,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,qBAAqB,GACrB,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC;IA2HvC;;;;;;OAMG;IACU,kBAAkB,CAAC,EAC/B,KAAK,EACL,aAAa,GACb,EAAE,0BAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAsB7D;;;;;;;;OAQG;IACU,oBAAoB,CAAC,EACjC,KAAK,EACL,aAAa,GACb,EAAE,0BAA0B,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAwB9D;;;;;OAKG;YACW,gBAAgB;YA4ChB,8BAA8B;CA6B5C"}
|