@velocity-exchange/sdk 0.9.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 +2 -2
- package/lib/browser/adminClient.js +3 -11
- package/lib/browser/equityFloorManager.d.ts +9 -5
- package/lib/browser/equityFloorManager.js +9 -5
- package/lib/browser/idl/velocity.d.ts +2 -1
- package/lib/browser/idl/velocity.json +2 -1
- package/lib/browser/index.d.ts +2 -0
- package/lib/browser/index.js +3 -0
- package/lib/browser/jupiter/jupiterClient.d.ts +31 -27
- package/lib/browser/jupiter/jupiterClient.js +61 -35
- package/lib/browser/math/margin.d.ts +12 -10
- package/lib/browser/math/margin.js +16 -14
- 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 +46 -117
- 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 +32 -68
- package/lib/browser/titan/titanClient.js +128 -102
- package/lib/browser/user.d.ts +16 -18
- package/lib/browser/user.js +24 -26
- package/lib/browser/velocityClient.d.ts +83 -101
- package/lib/browser/velocityClient.js +152 -289
- package/lib/node/adminClient.d.ts +2 -2
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +3 -11
- package/lib/node/equityFloorManager.d.ts +9 -5
- package/lib/node/equityFloorManager.d.ts.map +1 -1
- package/lib/node/equityFloorManager.js +9 -5
- package/lib/node/idl/velocity.d.ts +2 -1
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +2 -1
- package/lib/node/index.d.ts +2 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +3 -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 +61 -35
- package/lib/node/math/margin.d.ts +12 -10
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/math/margin.js +16 -14
- 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 +46 -117
- 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 +32 -68
- package/lib/node/titan/titanClient.d.ts.map +1 -1
- package/lib/node/titan/titanClient.js +128 -102
- package/lib/node/user.d.ts +16 -18
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +24 -26
- package/lib/node/velocityClient.d.ts +83 -101
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +152 -289
- package/package.json +1 -1
|
@@ -45,7 +45,7 @@ const spotPosition_1 = require("./math/spotPosition");
|
|
|
45
45
|
const market_1 = require("./math/market");
|
|
46
46
|
const fetch_1 = require("./accounts/fetch");
|
|
47
47
|
const spotMarket_1 = require("./math/spotMarket");
|
|
48
|
-
const
|
|
48
|
+
const UnifiedSwapClient_1 = require("./swap/UnifiedSwapClient");
|
|
49
49
|
const memcmp_1 = require("./memcmp");
|
|
50
50
|
const marinade_1 = require("./marinade");
|
|
51
51
|
const orderParams_1 = require("./orderParams");
|
|
@@ -61,8 +61,6 @@ const oracleId_1 = require("./oracles/oracleId");
|
|
|
61
61
|
const utils_3 = require("./oracles/utils");
|
|
62
62
|
const orders_1 = require("./math/orders");
|
|
63
63
|
const builder_1 = require("./math/builder");
|
|
64
|
-
const titanClient_1 = require("./titan/titanClient");
|
|
65
|
-
const UnifiedSwapClient_1 = require("./swap/UnifiedSwapClient");
|
|
66
64
|
/**
|
|
67
65
|
* # VelocityClient
|
|
68
66
|
* Main entry point for interacting with Velocity Exchange from TypeScript. A single instance wraps
|
|
@@ -3155,16 +3153,19 @@ class VelocityClient {
|
|
|
3155
3153
|
* @param fromSubAccountId - Sub-account id to debit.
|
|
3156
3154
|
* @param toSubAccountId - Sub-account id to credit.
|
|
3157
3155
|
* @param equityFloorDelta - Equity floor (QUOTE_PRECISION) to move from the debited to the credited
|
|
3158
|
-
* sub-account along with the funds, keeping the sum of floors constant.
|
|
3156
|
+
* sub-account along with the funds, keeping the sum of floors constant. A proportional share of
|
|
3157
|
+
* the debited side's `equityFloorBuffer` travels with the floor (rounded up on the debited side,
|
|
3158
|
+
* so shedding the whole floor also sheds the whole buffer; no orphan buffer is left on a
|
|
3159
|
+
* check-disabled sub-account), keeping the sum of buffers constant too. The debited side must not
|
|
3159
3160
|
* already be below the floor being reduced (a below-floor sub-account cannot shed floor to defuse a
|
|
3160
|
-
* pending equity-breaker trip), must stay at/above its reduced floor plus its
|
|
3161
|
-
* and the credited side's
|
|
3162
|
-
* its
|
|
3161
|
+
* pending equity-breaker trip), must stay at/above its reduced floor plus its reduced buffer,
|
|
3162
|
+
* and the credited side's net equity (after the transfer lands) must back its increased floor plus
|
|
3163
|
+
* its increased buffer, else the transfer reverts with `InvalidEquityFloorTransfer`. Pass `'auto'`
|
|
3163
3164
|
* (quote market only) to move the minimal floor needed for the debited side to stay at/above its
|
|
3164
|
-
* buffered floor: `max(0, amount - max(0,
|
|
3165
|
+
* buffered floor: `max(0, amount - max(0, netEquity - (floor + buffer)))`, capped at the debited
|
|
3165
3166
|
* side's floor (see `calculateEquityFloorAutoDelta`). The auto delta never exceeds `amount`, so the
|
|
3166
3167
|
* credited side stays backed whenever it was before. Client-side pricing can differ slightly from
|
|
3167
|
-
* the
|
|
3168
|
+
* the onchain check at the exact boundary; retry with an explicit padded delta if an
|
|
3168
3169
|
* `'auto'` transfer reverts. Defaults to zero.
|
|
3169
3170
|
* @param txParams - Optional compute-unit/priority-fee overrides for the transaction.
|
|
3170
3171
|
* @returns The transaction signature.
|
|
@@ -3203,7 +3204,7 @@ class VelocityClient {
|
|
|
3203
3204
|
}
|
|
3204
3205
|
const fromUserClass = this.getUser(fromSubAccountId, this.authority);
|
|
3205
3206
|
const fromUserAccount = fromUserClass.getUserAccountOrThrow();
|
|
3206
|
-
resolvedFloorDelta = (0, margin_1.calculateEquityFloorAutoDelta)(amount, fromUserClass.
|
|
3207
|
+
resolvedFloorDelta = (0, margin_1.calculateEquityFloorAutoDelta)(amount, fromUserClass.getNetUsdValue(), fromUserAccount.equityFloor, fromUserAccount.equityFloorBuffer);
|
|
3207
3208
|
}
|
|
3208
3209
|
else {
|
|
3209
3210
|
resolvedFloorDelta = equityFloorDelta;
|
|
@@ -4717,234 +4718,182 @@ class VelocityClient {
|
|
|
4717
4718
|
* instructions in a single transaction, so the swap is settled directly against the user's
|
|
4718
4719
|
* deposits/vault balances rather than the wallet's own token accounts. Sends and confirms the
|
|
4719
4720
|
* transaction.
|
|
4720
|
-
* @param swapClient -
|
|
4721
|
-
* `
|
|
4722
|
-
* @param jupiterClient - @deprecated Use `swapClient` instead.
|
|
4723
|
-
* not
|
|
4721
|
+
* @param swapClient - Provider used to quote the swap and build its route: a
|
|
4722
|
+
* `UnifiedSwapClient`, or a `TitanClient`/`JupiterClient` directly. See `getProviderSwapIx`.
|
|
4723
|
+
* @param jupiterClient - @deprecated Use `swapClient` instead. Used only when `swapClient` is
|
|
4724
|
+
* not passed.
|
|
4724
4725
|
* @param outMarketIndex - Spot market index of the token being bought.
|
|
4725
4726
|
* @param inMarketIndex - Spot market index of the token being sold.
|
|
4726
4727
|
* @param outAssociatedTokenAccount - Token account to receive the bought token; created
|
|
4727
4728
|
* idempotently if omitted.
|
|
4728
4729
|
* @param inAssociatedTokenAccount - Token account to source the sold token from; created
|
|
4729
4730
|
* idempotently if omitted.
|
|
4730
|
-
* @param amount - Amount of the "in" token (or "out" token when
|
|
4731
|
-
* which case this is the desired output amount), in the token's own mint
|
|
4732
|
-
* fixed protocol precision.
|
|
4731
|
+
* @param amount - Amount of the "in" token (or "out" token when the effective mode is
|
|
4732
|
+
* `ExactOut`, in which case this is the desired output amount), in the token's own mint
|
|
4733
|
+
* decimals — not a fixed protocol precision.
|
|
4733
4734
|
* @param slippageBps - Max slippage in basis points passed to the swap provider's routing API.
|
|
4734
|
-
* @param swapMode - `ExactIn` (default) or `ExactOut`.
|
|
4735
|
+
* @param swapMode - `ExactIn` (default) or `ExactOut`. Ignored when `quote` is passed — the
|
|
4736
|
+
* quote's own mode wins.
|
|
4735
4737
|
* @param reduceOnly - Whether the in/out token's position on the velocity account must reduce
|
|
4736
4738
|
* (not flip sign); enforced by `endSwap` after the swap completes.
|
|
4737
|
-
* @param
|
|
4738
|
-
*
|
|
4739
|
+
* @param quote - Pre-fetched quote (skips an extra round-trip to the swap provider). Must be
|
|
4740
|
+
* for this pair and this `amount`.
|
|
4739
4741
|
* @param txParams - Optional compute-unit/priority-fee overrides.
|
|
4740
|
-
* @throws If neither `swapClient` nor `jupiterClient` is provided
|
|
4741
|
-
* recognized client type.
|
|
4742
|
+
* @throws If neither `swapClient` nor `jupiterClient` is provided.
|
|
4742
4743
|
* @returns The transaction signature.
|
|
4743
4744
|
*/
|
|
4744
|
-
async swap({ swapClient,
|
|
4745
|
-
|
|
4746
|
-
const clientToUse = swapClient || jupiterClient;
|
|
4747
|
-
if (!clientToUse) {
|
|
4745
|
+
async swap({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, reduceOnly, txParams, quote, onlyDirectRoutes = false, }) {
|
|
4746
|
+
if (!swapClient) {
|
|
4748
4747
|
throw new Error('Either swapClient or jupiterClient must be provided');
|
|
4749
4748
|
}
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
reduceOnly,
|
|
4764
|
-
quote,
|
|
4765
|
-
v6,
|
|
4766
|
-
});
|
|
4767
|
-
}
|
|
4768
|
-
else if (clientToUse instanceof titanClient_1.TitanClient) {
|
|
4769
|
-
res = await this.getTitanSwapIx({
|
|
4770
|
-
titanClient: clientToUse,
|
|
4771
|
-
outMarketIndex,
|
|
4772
|
-
inMarketIndex,
|
|
4773
|
-
outAssociatedTokenAccount,
|
|
4774
|
-
inAssociatedTokenAccount,
|
|
4775
|
-
amount,
|
|
4776
|
-
slippageBps,
|
|
4777
|
-
swapMode,
|
|
4778
|
-
onlyDirectRoutes,
|
|
4779
|
-
reduceOnly,
|
|
4780
|
-
});
|
|
4781
|
-
}
|
|
4782
|
-
else if (clientToUse instanceof jupiterClient_1.JupiterClient) {
|
|
4783
|
-
const quoteToUse = quote !== null && quote !== void 0 ? quote : v6 === null || v6 === void 0 ? void 0 : v6.quote;
|
|
4784
|
-
res = await this.getJupiterSwapIxV6({
|
|
4785
|
-
jupiterClient: clientToUse,
|
|
4786
|
-
outMarketIndex,
|
|
4787
|
-
inMarketIndex,
|
|
4788
|
-
outAssociatedTokenAccount,
|
|
4789
|
-
inAssociatedTokenAccount,
|
|
4790
|
-
amount,
|
|
4791
|
-
slippageBps,
|
|
4792
|
-
swapMode,
|
|
4793
|
-
quote: quoteToUse,
|
|
4794
|
-
reduceOnly,
|
|
4795
|
-
onlyDirectRoutes,
|
|
4796
|
-
});
|
|
4797
|
-
}
|
|
4798
|
-
else {
|
|
4799
|
-
throw new Error('Invalid swap client type. Must be SwapClient, TitanClient, or JupiterClient.');
|
|
4800
|
-
}
|
|
4801
|
-
const ixs = res.ixs;
|
|
4802
|
-
const lookupTables = res.lookupTables;
|
|
4749
|
+
const { ixs, lookupTables } = await this.getProviderSwapIx({
|
|
4750
|
+
swapProvider: swapClient,
|
|
4751
|
+
outMarketIndex,
|
|
4752
|
+
inMarketIndex,
|
|
4753
|
+
outAssociatedTokenAccount,
|
|
4754
|
+
inAssociatedTokenAccount,
|
|
4755
|
+
amount,
|
|
4756
|
+
slippageBps,
|
|
4757
|
+
swapMode,
|
|
4758
|
+
onlyDirectRoutes,
|
|
4759
|
+
reduceOnly,
|
|
4760
|
+
quote,
|
|
4761
|
+
});
|
|
4803
4762
|
const tx = (await this.buildTransaction(ixs, txParams, 0, lookupTables));
|
|
4804
4763
|
const { txSig, slot } = await this.sendTransaction(tx);
|
|
4805
4764
|
this.cacheSpotMarketSlot(slot, outMarketIndex, inMarketIndex);
|
|
4806
4765
|
return txSig;
|
|
4807
4766
|
}
|
|
4808
4767
|
/**
|
|
4809
|
-
*
|
|
4810
|
-
*
|
|
4811
|
-
*
|
|
4812
|
-
*
|
|
4813
|
-
* created in the same transaction and not yet resolvable via `getUserAccountPublicKey`).
|
|
4814
|
-
* @returns `ixs` — instruction list (ATA creation, `beginSwap`, Titan swap instructions,
|
|
4815
|
-
* `endSwap`, in order) and `lookupTables` needed to fit it in a versioned transaction.
|
|
4768
|
+
* Throws unless a quote swaps exactly the pair the `beginSwap`/`endSwap` pair is being built
|
|
4769
|
+
* for. A mismatched quote routes and executes normally, but deposits its output into a token
|
|
4770
|
+
* account `endSwap` isn't watching, so it reverts with `InvalidSwap: amount_out must be
|
|
4771
|
+
* greater than 0` only after the funds have already moved.
|
|
4816
4772
|
*/
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4773
|
+
assertQuoteMatchesMarkets(quote, inMarket, outMarket) {
|
|
4774
|
+
if (!new web3_js_1.PublicKey(quote.inputMint).equals(inMarket.mint)) {
|
|
4775
|
+
throw new Error(`Quote sells ${quote.inputMint} but spot market ${inMarket.marketIndex} is ${inMarket.mint.toString()}.`);
|
|
4776
|
+
}
|
|
4777
|
+
if (!new web3_js_1.PublicKey(quote.outputMint).equals(outMarket.mint)) {
|
|
4778
|
+
throw new Error(`Quote buys ${quote.outputMint} but spot market ${outMarket.marketIndex} is ${outMarket.mint.toString()}.`);
|
|
4779
|
+
}
|
|
4780
|
+
}
|
|
4781
|
+
/**
|
|
4782
|
+
* Throws unless a quote is for the size the caller asked to swap. `beginSwap` releases funds
|
|
4783
|
+
* sized off the quote, so a quote for a different size moves the wrong amount out of the user's
|
|
4784
|
+
* deposits.
|
|
4785
|
+
*/
|
|
4786
|
+
assertQuoteMatchesAmount(quote, amount, swapMode) {
|
|
4820
4787
|
const isExactOut = swapMode === 'ExactOut';
|
|
4821
|
-
const
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
|
|
4825
|
-
outAssociatedTokenAccount = await this.getAssociatedTokenAccount(outMarket.marketIndex, false, tokenProgram);
|
|
4826
|
-
const accountInfo = await this.connection.getAccountInfo(outAssociatedTokenAccount);
|
|
4827
|
-
if (!accountInfo) {
|
|
4828
|
-
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(outAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint, tokenProgram));
|
|
4829
|
-
}
|
|
4788
|
+
const quoted = isExactOut ? quote.outAmount : quote.inAmount;
|
|
4789
|
+
if (quoted !== amount.toString()) {
|
|
4790
|
+
throw new Error(`Quote is for ${quoted} ${isExactOut ? 'out' : 'in'} but the swap asked for ${amount.toString()} (${swapMode}).`);
|
|
4830
4791
|
}
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4792
|
+
}
|
|
4793
|
+
/**
|
|
4794
|
+
* Resolves the wallet's associated token account for a spot market, plus the instruction that
|
|
4795
|
+
* creates it when it doesn't exist yet.
|
|
4796
|
+
*/
|
|
4797
|
+
async getOrCreateSwapTokenAccount(market) {
|
|
4798
|
+
const tokenProgram = this.getTokenProgramForSpotMarket(market);
|
|
4799
|
+
const tokenAccount = await this.getAssociatedTokenAccount(market.marketIndex, false, tokenProgram);
|
|
4800
|
+
if (await this.connection.getAccountInfo(tokenAccount)) {
|
|
4801
|
+
return { tokenAccount };
|
|
4838
4802
|
}
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
inTokenAccount: inAssociatedTokenAccount,
|
|
4844
|
-
outTokenAccount: outAssociatedTokenAccount,
|
|
4845
|
-
reduceOnly,
|
|
4846
|
-
userAccountPublicKey,
|
|
4847
|
-
});
|
|
4848
|
-
const { transactionMessage, lookupTables } = await titanClient.getSwap({
|
|
4849
|
-
inputMint: inMarket.mint,
|
|
4850
|
-
outputMint: outMarket.mint,
|
|
4851
|
-
amount,
|
|
4852
|
-
userPublicKey: this.provider.wallet.publicKey,
|
|
4853
|
-
slippageBps,
|
|
4854
|
-
swapMode: isExactOut ? titanClient_1.SwapMode.ExactOut : titanClient_1.SwapMode.ExactIn,
|
|
4855
|
-
onlyDirectRoutes,
|
|
4856
|
-
sizeConstraint: utils_2.MAX_TX_BYTE_SIZE - 375, // buffer for velocity instructions
|
|
4857
|
-
});
|
|
4858
|
-
const titanInstructions = titanClient.getTitanInstructions({
|
|
4859
|
-
transactionMessage,
|
|
4860
|
-
inputMint: inMarket.mint,
|
|
4861
|
-
outputMint: outMarket.mint,
|
|
4862
|
-
});
|
|
4863
|
-
const ixs = [
|
|
4864
|
-
...preInstructions,
|
|
4865
|
-
beginSwapIx,
|
|
4866
|
-
...titanInstructions,
|
|
4867
|
-
endSwapIx,
|
|
4868
|
-
];
|
|
4869
|
-
return { ixs, lookupTables };
|
|
4803
|
+
return {
|
|
4804
|
+
tokenAccount,
|
|
4805
|
+
createIx: this.createAssociatedTokenAccountIdempotentInstruction(tokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, market.mint, tokenProgram),
|
|
4806
|
+
};
|
|
4870
4807
|
}
|
|
4871
4808
|
/**
|
|
4872
|
-
* Builds the instruction list for a
|
|
4873
|
-
* creates any missing associated token accounts
|
|
4874
|
-
* between `beginSwap`/`endSwap`.
|
|
4875
|
-
*
|
|
4809
|
+
* Builds the instruction list for a swap routed through any `SwapProvider` (Jupiter, Titan, or
|
|
4810
|
+
* a `UnifiedSwapClient` wrapping either): creates any missing associated token accounts and
|
|
4811
|
+
* wraps the provider's routing instructions between `beginSwap`/`endSwap`.
|
|
4812
|
+
* @param swapProvider - Provider that quotes the swap and builds its route instructions.
|
|
4813
|
+
* @param outMarketIndex - Spot market index of the token being bought.
|
|
4814
|
+
* @param inMarketIndex - Spot market index of the token being sold.
|
|
4815
|
+
* @param outAssociatedTokenAccount - Token account to receive the bought token; created
|
|
4816
|
+
* idempotently if omitted.
|
|
4817
|
+
* @param inAssociatedTokenAccount - Token account to source the sold token from; created
|
|
4818
|
+
* idempotently if omitted.
|
|
4819
|
+
* @param amount - Amount in the "in" token's mint decimals, or the "out" token's when the
|
|
4820
|
+
* effective mode is `ExactOut`.
|
|
4821
|
+
* @param slippageBps - Max slippage in basis points; only used when a quote has to be fetched.
|
|
4822
|
+
* @param swapMode - `ExactIn` (default) or `ExactOut`. The mode a quote is fetched at; the
|
|
4823
|
+
* resulting quote's own mode is what sizes the swap, so it is ignored when `quote` is passed.
|
|
4824
|
+
* @param onlyDirectRoutes - Restricts a fetched quote to single-hop routes.
|
|
4825
|
+
* @param maxAccounts - Account budget for a fetched route.
|
|
4826
|
+
* @param reduceOnly - Which side must not increase in magnitude; enforced by `endSwap`.
|
|
4827
|
+
* @param quote - Pre-fetched quote. Authoritative when passed: its `swapMode` is the effective
|
|
4828
|
+
* mode, and it must be for this pair and this `amount`.
|
|
4876
4829
|
* @param userAccountPublicKey - Optional user account override (e.g. when the account is being
|
|
4877
|
-
* created in the same transaction).
|
|
4878
|
-
* @throws If
|
|
4879
|
-
*
|
|
4880
|
-
* `
|
|
4830
|
+
* created in the same transaction and not yet resolvable via `getUserAccountPublicKey`).
|
|
4831
|
+
* @throws If the quote — passed in or freshly fetched — is for a different pair or a different
|
|
4832
|
+
* size than the swap being built.
|
|
4833
|
+
* @returns `ixs` — ATA creation, `beginSwap`, the route's instructions, `endSwap`, in order —
|
|
4834
|
+
* and the `lookupTables` needed to fit them in a versioned transaction.
|
|
4881
4835
|
*/
|
|
4882
|
-
async
|
|
4836
|
+
async getProviderSwapIx({ swapProvider, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, maxAccounts, reduceOnly, quote, userAccountPublicKey, }) {
|
|
4837
|
+
var _a, _b;
|
|
4883
4838
|
const outMarket = this.getSpotMarketAccountOrThrow(outMarketIndex);
|
|
4884
4839
|
const inMarket = this.getSpotMarketAccountOrThrow(inMarketIndex);
|
|
4885
|
-
|
|
4886
|
-
const fetchedQuote = await jupiterClient.getQuote({
|
|
4887
|
-
inputMint: inMarket.mint,
|
|
4888
|
-
outputMint: outMarket.mint,
|
|
4889
|
-
amount,
|
|
4890
|
-
slippageBps,
|
|
4891
|
-
swapMode,
|
|
4892
|
-
onlyDirectRoutes,
|
|
4893
|
-
});
|
|
4894
|
-
quote = fetchedQuote;
|
|
4895
|
-
}
|
|
4896
|
-
if (!quote) {
|
|
4897
|
-
throw new Error('Could not fetch swap quote. Please try again.');
|
|
4898
|
-
}
|
|
4899
|
-
const isExactOut = swapMode === 'ExactOut' || quote.swapMode === 'ExactOut';
|
|
4900
|
-
const amountIn = new anchor_1.BN(quote.inAmount);
|
|
4901
|
-
const exactOutBufferedAmountIn = amountIn.muln(1001).divn(1000); // Add 10bp buffer
|
|
4902
|
-
const transaction = await jupiterClient.getSwap({
|
|
4903
|
-
quote,
|
|
4904
|
-
userPublicKey: this.provider.wallet.publicKey,
|
|
4905
|
-
slippageBps,
|
|
4906
|
-
});
|
|
4907
|
-
const { transactionMessage, lookupTables } = await jupiterClient.getTransactionMessageAndLookupTables({
|
|
4908
|
-
transaction,
|
|
4909
|
-
});
|
|
4910
|
-
const jupiterInstructions = jupiterClient.getJupiterInstructions({
|
|
4911
|
-
transactionMessage,
|
|
4840
|
+
const quoteToUse = quote !== null && quote !== void 0 ? quote : (await swapProvider.getQuote({
|
|
4912
4841
|
inputMint: inMarket.mint,
|
|
4913
4842
|
outputMint: outMarket.mint,
|
|
4914
|
-
|
|
4843
|
+
amount,
|
|
4844
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
4845
|
+
slippageBps,
|
|
4846
|
+
swapMode: swapMode !== null && swapMode !== void 0 ? swapMode : 'ExactIn',
|
|
4847
|
+
onlyDirectRoutes,
|
|
4848
|
+
maxAccounts,
|
|
4849
|
+
sizeConstraint: UnifiedSwapClient_1.DEFAULT_ROUTE_SIZE_CONSTRAINT,
|
|
4850
|
+
}));
|
|
4851
|
+
// The quote's own mode decides which side `amount` names and how `beginSwap` is sized, so it
|
|
4852
|
+
// wins over `swapMode` whether the quote was passed in or just fetched — a provider that
|
|
4853
|
+
// answers in the other mode is then caught by the size check rather than sizing the wrong side.
|
|
4854
|
+
const effectiveSwapMode = (_b = (_a = quoteToUse.swapMode) !== null && _a !== void 0 ? _a : swapMode) !== null && _b !== void 0 ? _b : 'ExactIn';
|
|
4855
|
+
// Both paths, identically: a freshly fetched quote is no more trustworthy about what it
|
|
4856
|
+
// priced than one handed to us.
|
|
4857
|
+
this.assertQuoteMatchesMarkets(quoteToUse, inMarket, outMarket);
|
|
4858
|
+
this.assertQuoteMatchesAmount(quoteToUse, amount, effectiveSwapMode);
|
|
4859
|
+
// Size `beginSwap` off the quote's own input: under ExactOut `amount` is the requested
|
|
4860
|
+
// output, so buffering it would be a guess at what the route consumes.
|
|
4861
|
+
const quotedAmountIn = new anchor_1.BN(quoteToUse.inAmount);
|
|
4862
|
+
const amountIn = effectiveSwapMode === 'ExactOut'
|
|
4863
|
+
? quotedAmountIn.muln(1001).divn(1000) // Add 10bp buffer
|
|
4864
|
+
: quotedAmountIn;
|
|
4915
4865
|
const preInstructions = [];
|
|
4916
4866
|
if (!outAssociatedTokenAccount) {
|
|
4917
|
-
const
|
|
4918
|
-
outAssociatedTokenAccount =
|
|
4919
|
-
|
|
4920
|
-
|
|
4921
|
-
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(outAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint, tokenProgram));
|
|
4867
|
+
const { tokenAccount, createIx } = await this.getOrCreateSwapTokenAccount(outMarket);
|
|
4868
|
+
outAssociatedTokenAccount = tokenAccount;
|
|
4869
|
+
if (createIx) {
|
|
4870
|
+
preInstructions.push(createIx);
|
|
4922
4871
|
}
|
|
4923
4872
|
}
|
|
4924
4873
|
if (!inAssociatedTokenAccount) {
|
|
4925
|
-
const
|
|
4926
|
-
inAssociatedTokenAccount =
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(inAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, inMarket.mint, tokenProgram));
|
|
4874
|
+
const { tokenAccount, createIx } = await this.getOrCreateSwapTokenAccount(inMarket);
|
|
4875
|
+
inAssociatedTokenAccount = tokenAccount;
|
|
4876
|
+
if (createIx) {
|
|
4877
|
+
preInstructions.push(createIx);
|
|
4930
4878
|
}
|
|
4931
4879
|
}
|
|
4932
4880
|
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
4933
4881
|
outMarketIndex,
|
|
4934
4882
|
inMarketIndex,
|
|
4935
|
-
amountIn
|
|
4883
|
+
amountIn,
|
|
4936
4884
|
inTokenAccount: inAssociatedTokenAccount,
|
|
4937
4885
|
outTokenAccount: outAssociatedTokenAccount,
|
|
4938
4886
|
reduceOnly,
|
|
4939
4887
|
userAccountPublicKey,
|
|
4940
4888
|
});
|
|
4941
|
-
const
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4889
|
+
const { instructions: routeInstructions, lookupTables } = await swapProvider.getRouteInstructions({
|
|
4890
|
+
quote: quoteToUse,
|
|
4891
|
+
userPublicKey: this.provider.wallet.publicKey,
|
|
4892
|
+
});
|
|
4893
|
+
return {
|
|
4894
|
+
ixs: [...preInstructions, beginSwapIx, ...routeInstructions, endSwapIx],
|
|
4895
|
+
lookupTables,
|
|
4896
|
+
};
|
|
4948
4897
|
}
|
|
4949
4898
|
/**
|
|
4950
4899
|
* Builds the `beginSwap`/`endSwap` instruction pair that must bracket an external swap
|
|
@@ -5049,88 +4998,6 @@ class VelocityClient {
|
|
|
5049
4998
|
});
|
|
5050
4999
|
return { beginSwapIx, endSwapIx };
|
|
5051
5000
|
}
|
|
5052
|
-
/**
|
|
5053
|
-
* Builds the instruction list for a swap routed through a `UnifiedSwapClient` (the current
|
|
5054
|
-
* preferred swap path). Creates any missing associated token accounts and wraps the client's
|
|
5055
|
-
* routing instructions between `beginSwap`/`endSwap`. See `swap` for parameter semantics;
|
|
5056
|
-
* `amount` is in the "in" token's mint decimals (or "out" token's decimals when `swapMode` is
|
|
5057
|
-
* `ExactOut`).
|
|
5058
|
-
* @param userAccountPublicKey - Optional user account override (e.g. when the account is being
|
|
5059
|
-
* created in the same transaction).
|
|
5060
|
-
* @returns `ixs` — instruction list (ATA creation, `beginSwap`, routed swap instructions,
|
|
5061
|
-
* `endSwap`, in order) and `lookupTables` needed to fit it in a versioned transaction.
|
|
5062
|
-
*/
|
|
5063
|
-
async getSwapIxV2({ swapClient, outMarketIndex, inMarketIndex, outAssociatedTokenAccount, inAssociatedTokenAccount, amount, slippageBps, swapMode, onlyDirectRoutes, reduceOnly, quote, v6, userAccountPublicKey, }) {
|
|
5064
|
-
// Get market accounts to determine mints
|
|
5065
|
-
const outMarket = this.getSpotMarketAccountOrThrow(outMarketIndex);
|
|
5066
|
-
const inMarket = this.getSpotMarketAccountOrThrow(inMarketIndex);
|
|
5067
|
-
const isExactOut = swapMode === 'ExactOut';
|
|
5068
|
-
const preInstructions = [];
|
|
5069
|
-
// Handle token accounts if not provided
|
|
5070
|
-
let finalOutAssociatedTokenAccount = outAssociatedTokenAccount;
|
|
5071
|
-
let finalInAssociatedTokenAccount = inAssociatedTokenAccount;
|
|
5072
|
-
if (!finalOutAssociatedTokenAccount) {
|
|
5073
|
-
const tokenProgram = this.getTokenProgramForSpotMarket(outMarket);
|
|
5074
|
-
finalOutAssociatedTokenAccount = await this.getAssociatedTokenAccount(outMarket.marketIndex, false, tokenProgram);
|
|
5075
|
-
const accountInfo = await this.connection.getAccountInfo(finalOutAssociatedTokenAccount);
|
|
5076
|
-
if (!accountInfo) {
|
|
5077
|
-
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(finalOutAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, outMarket.mint, tokenProgram));
|
|
5078
|
-
}
|
|
5079
|
-
}
|
|
5080
|
-
if (!finalInAssociatedTokenAccount) {
|
|
5081
|
-
const tokenProgram = this.getTokenProgramForSpotMarket(inMarket);
|
|
5082
|
-
finalInAssociatedTokenAccount = await this.getAssociatedTokenAccount(inMarket.marketIndex, false, tokenProgram);
|
|
5083
|
-
const accountInfo = await this.connection.getAccountInfo(finalInAssociatedTokenAccount);
|
|
5084
|
-
if (!accountInfo) {
|
|
5085
|
-
preInstructions.push(this.createAssociatedTokenAccountIdempotentInstruction(finalInAssociatedTokenAccount, this.provider.wallet.publicKey, this.provider.wallet.publicKey, inMarket.mint, tokenProgram));
|
|
5086
|
-
}
|
|
5087
|
-
}
|
|
5088
|
-
let amountInForBeginSwap;
|
|
5089
|
-
if (isExactOut) {
|
|
5090
|
-
if (quote || (v6 === null || v6 === void 0 ? void 0 : v6.quote)) {
|
|
5091
|
-
amountInForBeginSwap = (v6 === null || v6 === void 0 ? void 0 : v6.quote)
|
|
5092
|
-
? new anchor_1.BN(v6.quote.inAmount)
|
|
5093
|
-
: new anchor_1.BN(quote.inAmount);
|
|
5094
|
-
}
|
|
5095
|
-
else {
|
|
5096
|
-
amountInForBeginSwap = amount.muln(1001).divn(1000);
|
|
5097
|
-
}
|
|
5098
|
-
}
|
|
5099
|
-
else {
|
|
5100
|
-
amountInForBeginSwap = amount;
|
|
5101
|
-
}
|
|
5102
|
-
// Get velocity swap instructions for begin and end
|
|
5103
|
-
const { beginSwapIx, endSwapIx } = await this.getSwapIx({
|
|
5104
|
-
outMarketIndex,
|
|
5105
|
-
inMarketIndex,
|
|
5106
|
-
amountIn: amountInForBeginSwap,
|
|
5107
|
-
inTokenAccount: finalInAssociatedTokenAccount,
|
|
5108
|
-
outTokenAccount: finalOutAssociatedTokenAccount,
|
|
5109
|
-
reduceOnly,
|
|
5110
|
-
userAccountPublicKey,
|
|
5111
|
-
});
|
|
5112
|
-
// Get core swap instructions from SwapClient
|
|
5113
|
-
const swapResult = await swapClient.getSwapInstructions({
|
|
5114
|
-
inputMint: inMarket.mint,
|
|
5115
|
-
outputMint: outMarket.mint,
|
|
5116
|
-
amount,
|
|
5117
|
-
userPublicKey: this.provider.wallet.publicKey,
|
|
5118
|
-
slippageBps,
|
|
5119
|
-
swapMode,
|
|
5120
|
-
onlyDirectRoutes,
|
|
5121
|
-
quote: quote !== null && quote !== void 0 ? quote : v6 === null || v6 === void 0 ? void 0 : v6.quote,
|
|
5122
|
-
});
|
|
5123
|
-
const allInstructions = [
|
|
5124
|
-
...preInstructions,
|
|
5125
|
-
beginSwapIx,
|
|
5126
|
-
...swapResult.instructions,
|
|
5127
|
-
endSwapIx,
|
|
5128
|
-
];
|
|
5129
|
-
return {
|
|
5130
|
-
ixs: allInstructions,
|
|
5131
|
-
lookupTables: swapResult.lookupTables,
|
|
5132
|
-
};
|
|
5133
|
-
}
|
|
5134
5001
|
/**
|
|
5135
5002
|
* Converts a portion of the user's deposited wSOL (spot market index 1) into mSOL (spot market
|
|
5136
5003
|
* index 2) by staking it with Marinade Finance, then swapping the resulting mSOL back into the
|
|
@@ -5274,11 +5141,12 @@ class VelocityClient {
|
|
|
5274
5141
|
}
|
|
5275
5142
|
/**
|
|
5276
5143
|
* Keeper instruction: trips the authority-wide equity floor breaker. Proves on-chain that the
|
|
5277
|
-
* given subaccount's
|
|
5278
|
-
* `SufficientCollateral` otherwise,
|
|
5279
|
-
*
|
|
5280
|
-
*
|
|
5281
|
-
*
|
|
5144
|
+
* given subaccount's net equity (unweighted assets and perp PnL minus spot liabilities) is below
|
|
5145
|
+
* its `equityFloor` (reverts with `SufficientCollateral` otherwise, if no floor is set, or with
|
|
5146
|
+
* `InvalidOracle` if any of the subaccount's oracles is invalid) and sets `equityBreakerTripped`
|
|
5147
|
+
* on the authority's `UserStats` — every subaccount of the authority then rejects risk-increasing
|
|
5148
|
+
* fills, withdrawals and transfers out until the warm admin calls `resetEquityFloorBreaker`.
|
|
5149
|
+
* Permissionless — any signer may trip it; the equity calculation is the proof.
|
|
5282
5150
|
* @param userAccountPublicKey - Public key of the breached subaccount's user account.
|
|
5283
5151
|
* @param user - Decoded user account of the breached subaccount.
|
|
5284
5152
|
* @param txParams - Optional compute-unit/priority-fee overrides.
|
|
@@ -6798,11 +6666,13 @@ class VelocityClient {
|
|
|
6798
6666
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
6799
6667
|
* @param liquidatorSubAccountId - Liquidator's sub-account to credit; defaults to the active sub-account.
|
|
6800
6668
|
* @param maxAccounts - Caps the number of accounts Jupiter's route may use.
|
|
6801
|
-
* @throws If no quote can be fetched and `quote` was not supplied
|
|
6669
|
+
* @throws If no quote can be fetched and `quote` was not supplied, or if the quote — passed in or
|
|
6670
|
+
* freshly fetched — is for a different pair or a different size than the swap being built.
|
|
6802
6671
|
* @returns The ordered instructions (pre-instructions, `beginSwap`, Jupiter swap, `endSwap`) and
|
|
6803
6672
|
* any address lookup tables the Jupiter route requires.
|
|
6804
6673
|
*/
|
|
6805
6674
|
async getJupiterLiquidateSpotWithSwapIxV6({ jupiterClient, liabilityMarketIndex, assetMarketIndex, swapAmount, assetTokenAccount, liabilityTokenAccount, slippageBps, swapMode, onlyDirectRoutes, quote, userAccount, userAccountPublicKey, liquidatorSubAccountId, maxAccounts, }) {
|
|
6675
|
+
var _a, _b;
|
|
6806
6676
|
const liabilityMarket = this.getSpotMarketAccountOrThrow(liabilityMarketIndex);
|
|
6807
6677
|
const assetMarket = this.getSpotMarketAccountOrThrow(assetMarketIndex);
|
|
6808
6678
|
if (!quote) {
|
|
@@ -6820,19 +6690,12 @@ class VelocityClient {
|
|
|
6820
6690
|
if (!quote) {
|
|
6821
6691
|
throw new Error('Could not fetch swap quote. Please try again.');
|
|
6822
6692
|
}
|
|
6693
|
+
this.assertQuoteMatchesMarkets(quote, assetMarket, liabilityMarket);
|
|
6694
|
+
this.assertQuoteMatchesAmount(quote, swapAmount, (_b = (_a = quote.swapMode) !== null && _a !== void 0 ? _a : swapMode) !== null && _b !== void 0 ? _b : 'ExactIn');
|
|
6823
6695
|
const amountIn = new anchor_1.BN(quote.inAmount);
|
|
6824
|
-
const
|
|
6696
|
+
const { instructions: jupiterInstructions, lookupTables } = await jupiterClient.getRouteInstructions({
|
|
6825
6697
|
quote,
|
|
6826
6698
|
userPublicKey: this.provider.wallet.publicKey,
|
|
6827
|
-
slippageBps,
|
|
6828
|
-
});
|
|
6829
|
-
const { transactionMessage, lookupTables } = await jupiterClient.getTransactionMessageAndLookupTables({
|
|
6830
|
-
transaction,
|
|
6831
|
-
});
|
|
6832
|
-
const jupiterInstructions = jupiterClient.getJupiterInstructions({
|
|
6833
|
-
transactionMessage,
|
|
6834
|
-
inputMint: assetMarket.mint,
|
|
6835
|
-
outputMint: liabilityMarket.mint,
|
|
6836
6699
|
});
|
|
6837
6700
|
const preInstructions = [];
|
|
6838
6701
|
if (!liabilityTokenAccount) {
|