@velocity-exchange/sdk 0.2.4 → 0.3.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/CHANGELOG.md +60 -4
- package/README.md +8 -8
- package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +0 -1
- package/lib/browser/accounts/grpcMultiAccountSubscriber.js +2 -7
- package/lib/browser/accounts/grpcMultiUserAccountSubscriber.js +3 -0
- package/lib/browser/accounts/webSocketAccountSubscriberV2.js +1 -2
- package/lib/browser/accounts/websocketProgramUserAccountSubscriber.js +3 -0
- package/lib/browser/adminClient.d.ts +3 -1
- package/lib/browser/adminClient.js +16 -0
- package/lib/browser/idl/velocity.d.ts +50 -1
- package/lib/browser/idl/velocity.json +50 -1
- package/lib/browser/math/exchangeStatus.d.ts +1 -0
- package/lib/browser/math/exchangeStatus.js +8 -1
- package/lib/browser/math/orders.d.ts +3 -0
- package/lib/browser/math/orders.js +6 -2
- package/lib/browser/math/state.js +1 -1
- package/lib/browser/memcmp.js +26 -5
- package/lib/browser/orderSubscriber/OrderSubscriber.js +11 -2
- package/lib/browser/swift/swiftOrderSubscriber.js +2 -2
- package/lib/browser/tokenFaucet.d.ts +2 -2
- package/lib/browser/tokenFaucet.js +11 -4
- package/lib/browser/types.d.ts +5 -0
- package/lib/browser/types.js +9 -2
- package/lib/browser/user.d.ts +22 -6
- package/lib/browser/user.js +24 -8
- package/lib/browser/velocityClient.d.ts +1 -3
- package/lib/browser/velocityClient.js +16 -22
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +0 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiAccountSubscriber.js +2 -7
- package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/grpcMultiUserAccountSubscriber.js +3 -0
- package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts.map +1 -1
- package/lib/node/accounts/webSocketAccountSubscriberV2.js +1 -2
- package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts.map +1 -1
- package/lib/node/accounts/websocketProgramUserAccountSubscriber.js +3 -0
- package/lib/node/adminClient.d.ts +3 -1
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +16 -0
- package/lib/node/idl/velocity.d.ts +50 -1
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +50 -1
- package/lib/node/math/exchangeStatus.d.ts +1 -0
- package/lib/node/math/exchangeStatus.d.ts.map +1 -1
- package/lib/node/math/exchangeStatus.js +8 -1
- package/lib/node/math/orders.d.ts +3 -0
- package/lib/node/math/orders.d.ts.map +1 -1
- package/lib/node/math/orders.js +6 -2
- package/lib/node/math/state.js +1 -1
- package/lib/node/memcmp.d.ts.map +1 -1
- package/lib/node/memcmp.js +26 -5
- package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
- package/lib/node/orderSubscriber/OrderSubscriber.js +11 -2
- package/lib/node/swift/swiftOrderSubscriber.js +2 -2
- package/lib/node/tokenFaucet.d.ts +2 -2
- package/lib/node/tokenFaucet.d.ts.map +1 -1
- package/lib/node/tokenFaucet.js +11 -4
- package/lib/node/types.d.ts +5 -0
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/types.js +9 -2
- package/lib/node/user.d.ts +22 -6
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +24 -8
- package/lib/node/velocityClient.d.ts +1 -3
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +16 -22
- package/package.json +2 -2
- package/src/accounts/grpcMultiAccountSubscriber.ts +2 -10
- package/src/accounts/grpcMultiUserAccountSubscriber.ts +5 -0
- package/src/accounts/webSocketAccountSubscriberV2.ts +1 -5
- package/src/accounts/websocketProgramUserAccountSubscriber.ts +5 -0
- package/src/adminClient.ts +28 -0
- package/src/idl/velocity.json +50 -1
- package/src/idl/velocity.ts +50 -1
- package/src/math/exchangeStatus.ts +10 -0
- package/src/math/orders.ts +6 -2
- package/src/math/state.ts +1 -1
- package/src/memcmp.ts +27 -5
- package/src/orderSubscriber/OrderSubscriber.ts +18 -2
- package/src/swift/swiftOrderSubscriber.ts +2 -2
- package/src/tokenFaucet.ts +10 -7
- package/src/types.ts +8 -0
- package/src/user.ts +24 -8
- package/src/velocityClient.ts +17 -36
- package/tests/dlob/helpers.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,25 +1,81 @@
|
|
|
1
1
|
# @velocity-exchange/sdk
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#172](https://github.com/velocity-exchange/velocity-v1/pull/172) [`b7d15b9`](https://github.com/velocity-exchange/velocity-v1/commit/b7d15b970a74d267aeaf20bb644d5344b9aadc61) Thanks [@0xahzam](https://github.com/0xahzam)! - Decouple solvency-repair from the withdraw pause. The `resolve_perp_pnl_deficit`,
|
|
8
|
+
`resolve_perp_bankruptcy`, and `resolve_spot_bankruptcy` instructions are now gated by a
|
|
9
|
+
new `State.solvencyStatus` bitfield instead of `WithdrawPaused`, so user withdrawals can
|
|
10
|
+
be halted while solvency repair keeps running (or repair can be frozen on its own). Adds
|
|
11
|
+
the `SolvencyStatus` enum, `StateAccount.solvencyStatus`, a `solvencyRepairPaused()`
|
|
12
|
+
helper, `AdminClient.updateSolvencyStatus`, and the `exchange set-solvency-status` admin
|
|
13
|
+
CLI command.
|
|
14
|
+
|
|
15
|
+
- [#141](https://github.com/velocity-exchange/velocity-v1/pull/141) [`3f148f8`](https://github.com/velocity-exchange/velocity-v1/commit/3f148f8b477e4176e11e0660adb0e67dd5163d3b) Thanks [@ChewingGlass](https://github.com/ChewingGlass)! - Harden the native fast-path admin handlers. The
|
|
16
|
+
`update_amm_spread_adjustment_native` instruction now requires the program
|
|
17
|
+
`State` account: `getUpdateAmmSpreadAdjustmentNativeIx` is now **async** and
|
|
18
|
+
returns a `Promise<TransactionInstruction>` (it derives and appends the state
|
|
19
|
+
account), and its compute-unit budget was raised to cover the on-chain account
|
|
20
|
+
validation. Direct callers must `await` the builder. Two new program error
|
|
21
|
+
codes are surfaced in the IDL: `InvalidNativeStateAccount` (6355) and
|
|
22
|
+
`InvalidNativePerpMarketAccount` (6356).
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- [#173](https://github.com/velocity-exchange/velocity-v1/pull/173) [`2f6c64d`](https://github.com/velocity-exchange/velocity-v1/commit/2f6c64d54f1146d8e7f9ee4ab556929c6bf8b920) Thanks [@ChesterSim](https://github.com/ChesterSim)! - Fix stale `User` account byte offsets in `memcmp` filters and `OrderSubscriber`.
|
|
27
|
+
|
|
28
|
+
The Velocity `User` account is 4496 bytes, but the memcmp filters and the
|
|
29
|
+
`OrderSubscriber` staleness check still used offsets from the older 4376-byte
|
|
30
|
+
layout. As a result `getUserWithOrderFilter()` matched zero accounts, so any
|
|
31
|
+
consumer that bulk-loads users-with-orders (e.g. the DLOB server's
|
|
32
|
+
`OrderSubscriber.fetch()`) loaded no orders and produced an empty order book
|
|
33
|
+
(vAMM-only L2, empty L3). Offsets for `idle`, `hasOpenOrder`, `hasOpenAuction`,
|
|
34
|
+
`poolId`, and `lastActiveSlot` are corrected to match the on-chain layout.
|
|
35
|
+
|
|
36
|
+
## 0.2.6
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- [#156](https://github.com/velocity-exchange/velocity-v1/pull/156) [`d3b58ab`](https://github.com/velocity-exchange/velocity-v1/commit/d3b58ab7e3ad33f0e6634ff87e9b150915b3aa13) Thanks [@ChesterSim](https://github.com/ChesterSim)! - Fix account decoder to pass account names as-is instead of capitalizing them. The
|
|
41
|
+
Anchor v1 IDL program constructor already camelCases account names, so the extra
|
|
42
|
+
`capitalize()` call was incorrect and caused decoding failures in the gRPC and
|
|
43
|
+
WebSocket subscribers.
|
|
44
|
+
|
|
45
|
+
## 0.2.5
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- [#155](https://github.com/velocity-exchange/velocity-v1/pull/155) [`15073bc`](https://github.com/velocity-exchange/velocity-v1/commit/15073bc0b740b2d1cad471126a00368e72655bd5) Thanks [@ChesterSim](https://github.com/ChesterSim)! - Make the `UserAccountSubscriber` "not subscribed" contract consistent and fix a
|
|
50
|
+
misleading error message. `getUserAccountAndSlot()` now throws `NotSubscribedError`
|
|
51
|
+
when called before `subscribe()` on the gRPC-multi and WebSocket-program subscribers
|
|
52
|
+
too (the WebSocket and polling subscribers already did) — so `User.getUserAccount()`
|
|
53
|
+
uniformly throws when not subscribed and returns `undefined` only when subscribed but
|
|
54
|
+
the account was not found on chain. `getUserAccountOrThrow()` /
|
|
55
|
+
`getUserAccountAndSlotOrThrow()` now throw `User account not found: <pubkey>` (was
|
|
56
|
+
`User account not loaded`), since after `subscribe()` resolves a missing account means
|
|
57
|
+
"not found", not "still loading".
|
|
58
|
+
|
|
3
59
|
## 0.2.4
|
|
4
60
|
|
|
5
61
|
### Patch Changes
|
|
6
62
|
|
|
7
|
-
- [#127](https://github.com/
|
|
63
|
+
- [#127](https://github.com/velocity-exchange/velocity-v1/pull/127) [`4f8e7aa`](https://github.com/velocity-exchange/velocity-v1/commit/4f8e7aaef0e35b190fc0b91cd29314d902d1ccab) Thanks [@ChesterSim](https://github.com/ChesterSim)! - reflect Typescript types on IDL changes
|
|
8
64
|
|
|
9
65
|
## 0.2.3
|
|
10
66
|
|
|
11
67
|
### Patch Changes
|
|
12
68
|
|
|
13
|
-
- [#100](https://github.com/
|
|
69
|
+
- [#100](https://github.com/velocity-exchange/velocity-v1/pull/100) [`ae78769`](https://github.com/velocity-exchange/velocity-v1/commit/ae78769ef58355202c030435c2796ef045fe30a0) Thanks [@ChesterSim](https://github.com/ChesterSim)! - add back ForwardOnlyTxSender and calculateMaxRemainingDeposit
|
|
14
70
|
|
|
15
71
|
## 0.2.2
|
|
16
72
|
|
|
17
73
|
### Patch Changes
|
|
18
74
|
|
|
19
|
-
- [#97](https://github.com/
|
|
75
|
+
- [#97](https://github.com/velocity-exchange/velocity-v1/pull/97) [`022a949`](https://github.com/velocity-exchange/velocity-v1/commit/022a949cb1802171ca57a61260f86c8908f94f34) Thanks [@ChewingGlass](https://github.com/ChewingGlass)! - Re-export `PriceUpdateAccount` from the package root and declare `@types/node` as a devDependency (fixes the SDK build under isolated installs). Enables downstream apps (dlob-server, keeper-bots-v2) to consume the velocity SDK without reaching into subpaths.
|
|
20
76
|
|
|
21
77
|
## 0.2.1
|
|
22
78
|
|
|
23
79
|
### Patch Changes
|
|
24
80
|
|
|
25
|
-
- [`4fd7462`](https://github.com/
|
|
81
|
+
- [`4fd7462`](https://github.com/velocity-exchange/velocity-v1/commit/4fd7462bfa3c55e31e3457b1b65f519cf052a6fa) Thanks [@ChewingGlass](https://github.com/ChewingGlass)! - Testing new changelog based package publishing flow
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<img height="120" src="https://raw.githubusercontent.com/
|
|
2
|
+
<img height="120" src="https://raw.githubusercontent.com/velocity-exchange/velocity-v1/master/assets/velocity-logo.svg" />
|
|
3
3
|
|
|
4
4
|
<h1 style="margin-top:20px;">Velocity Exchange</h1>
|
|
5
5
|
|
|
6
6
|
<p>
|
|
7
7
|
<a href="https://www.npmjs.com/package/@velocity-exchange/sdk"><img alt="SDK npm package" src="https://img.shields.io/npm/v/@velocity-exchange/sdk" /></a>
|
|
8
|
-
<a href="https://
|
|
8
|
+
<a href="https://velocity-exchange.github.io/protocol-v2/sdk/"><img alt="Docs" src="https://img.shields.io/badge/docs-tutorials-blueviolet" /></a>
|
|
9
9
|
<a href="https://discord.com/channels/849494028176588802/878700556904980500"><img alt="Discord Chat" src="https://img.shields.io/discord/889577356681945098?color=blueviolet" /></a>
|
|
10
10
|
<a href="https://opensource.org/licenses/Apache-2.0"><img alt="License" src="https://img.shields.io/github/license/project-serum/anchor?color=blueviolet" /></a>
|
|
11
11
|
</p>
|
|
@@ -21,18 +21,18 @@ npm i @velocity-exchange/sdk
|
|
|
21
21
|
|
|
22
22
|
_Start here if you're integrating with Velocity!_
|
|
23
23
|
|
|
24
|
-
- [Velocity v2-teacher + API Docs](https://
|
|
24
|
+
- [Velocity v2-teacher + API Docs](https://velocity-exchange.github.io/v2-teacher/)
|
|
25
25
|
- Docs and examples for using the SDK in Typescript and Python
|
|
26
26
|
- Useful concepts and examples when integrating Velocity
|
|
27
27
|
- Docs for Velocity's "Data API"
|
|
28
|
-
- [Typescript API docs](https://
|
|
29
|
-
- JSDoc automated documentation for the Velocity
|
|
28
|
+
- [Typescript API docs](https://velocity-exchange.github.io/protocol-v2/sdk/)
|
|
29
|
+
- JSDoc automated documentation for the Velocity v1 Typescript SDK
|
|
30
30
|
- [Velocity docs](https://docs.drift.trade/)
|
|
31
31
|
- Comprehensive universal docs for Velocity
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
35
|
-
The below is a light overview of using Solana and Velocity's typescript sdk. If you want comprehensive docs with examples of how to integrate with Velocity you should use the [v2-teacher docs](https://
|
|
35
|
+
The below is a light overview of using Solana and Velocity's typescript sdk. If you want comprehensive docs with examples of how to integrate with Velocity you should use the [v2-teacher docs](https://velocity-exchange.github.io/v2-teacher/).
|
|
36
36
|
|
|
37
37
|
### Setting up a wallet for your program
|
|
38
38
|
|
|
@@ -210,7 +210,7 @@ const main = async () => {
|
|
|
210
210
|
provider.wallet.publicKey.toString()
|
|
211
211
|
);
|
|
212
212
|
|
|
213
|
-
//// Create a Velocity
|
|
213
|
+
//// Create a Velocity V1 account by Depositing some USDC ($10,000 in this case)
|
|
214
214
|
const depositAmount = new BN(10000).mul(QUOTE_PRECISION);
|
|
215
215
|
await velocityClient.initializeUserAccountAndDepositCollateral(
|
|
216
216
|
depositAmount,
|
|
@@ -267,7 +267,7 @@ main();
|
|
|
267
267
|
|
|
268
268
|
## License
|
|
269
269
|
|
|
270
|
-
Velocity Protocol
|
|
270
|
+
Velocity Protocol v1 is licensed under [Apache 2.0](./LICENSE).
|
|
271
271
|
|
|
272
272
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
273
273
|
for inclusion in Velocity SDK by you, as defined in the Apache-2.0 license, shall be
|
|
@@ -125,7 +125,7 @@ class grpcMultiAccountSubscriber {
|
|
|
125
125
|
buffer: newBuffer,
|
|
126
126
|
slot: currentSlot,
|
|
127
127
|
});
|
|
128
|
-
const accountDecoded = this.program.coder.accounts.decode(this.
|
|
128
|
+
const accountDecoded = this.program.coder.accounts.decode(this.accountName, newBuffer);
|
|
129
129
|
this.setAccountData(accountId, accountDecoded, currentSlot);
|
|
130
130
|
}
|
|
131
131
|
}
|
|
@@ -220,7 +220,7 @@ class grpcMultiAccountSubscriber {
|
|
|
220
220
|
const handleDataBuffer = (context, buffer, accountProps) => {
|
|
221
221
|
const data = this.decodeBufferFn
|
|
222
222
|
? this.decodeBufferFn(buffer, accountPubkey, accountProps)
|
|
223
|
-
: this.program.coder.accounts.decode(this.
|
|
223
|
+
: this.program.coder.accounts.decode(this.accountName, buffer);
|
|
224
224
|
const handler = this.onChangeMap.get(accountPubkey);
|
|
225
225
|
if (handler) {
|
|
226
226
|
handler(data, context, buffer, accountProps);
|
|
@@ -377,10 +377,5 @@ class grpcMultiAccountSubscriber {
|
|
|
377
377
|
}
|
|
378
378
|
}, (_a = this.resubOpts) === null || _a === void 0 ? void 0 : _a.resubTimeoutMs);
|
|
379
379
|
}
|
|
380
|
-
capitalize(value) {
|
|
381
|
-
if (!value)
|
|
382
|
-
return value;
|
|
383
|
-
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
384
|
-
}
|
|
385
380
|
}
|
|
386
381
|
exports.grpcMultiAccountSubscriber = grpcMultiAccountSubscriber;
|
|
@@ -146,6 +146,9 @@ class grpcMultiUserAccountSubscriber {
|
|
|
146
146
|
isSubscribed = false;
|
|
147
147
|
},
|
|
148
148
|
getUserAccountAndSlot() {
|
|
149
|
+
if (!isSubscribed) {
|
|
150
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
151
|
+
}
|
|
149
152
|
return parent.userData.get(key);
|
|
150
153
|
},
|
|
151
154
|
};
|
|
@@ -4,7 +4,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.WebSocketAccountSubscriberV2 = void 0;
|
|
7
|
-
const utils_1 = require("./utils");
|
|
8
7
|
const gill_1 = require("gill");
|
|
9
8
|
const bs58_1 = __importDefault(require("bs58"));
|
|
10
9
|
/**
|
|
@@ -376,7 +375,7 @@ class WebSocketAccountSubscriberV2 {
|
|
|
376
375
|
return this.decodeBufferFn(buffer);
|
|
377
376
|
}
|
|
378
377
|
else {
|
|
379
|
-
return this.program.coder.accounts.decode(
|
|
378
|
+
return this.program.coder.accounts.decode(this.accountName, buffer);
|
|
380
379
|
}
|
|
381
380
|
}
|
|
382
381
|
unsubscribe(onResub = false) {
|
|
@@ -45,6 +45,9 @@ class WebSocketProgramUserAccountSubscriber {
|
|
|
45
45
|
this.isSubscribed = false;
|
|
46
46
|
}
|
|
47
47
|
getUserAccountAndSlot() {
|
|
48
|
+
if (!this.isSubscribed) {
|
|
49
|
+
throw new types_1.NotSubscribedError('You must call `subscribe` before using this function');
|
|
50
|
+
}
|
|
48
51
|
return this.userAccountAndSlot;
|
|
49
52
|
}
|
|
50
53
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* pause/unpause exchange, and all ~126 admin instruction handlers in `instructions/admin.rs`.
|
|
8
8
|
*/
|
|
9
9
|
import { AddressLookupTableAccount, Keypair, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
10
|
-
import { FeeStructure, OracleGuardRails, OracleSource, ExchangeStatus, MarketStatus, ContractTier, AssetTier, TxParams, AddAmmConstituentMappingDatum, SwapReduceOnly, InitializeConstituentParams, ConstituentStatus, LPPoolAccount, TransferFeeAndPnlPoolDirection, MarketType } from './types';
|
|
10
|
+
import { FeeStructure, OracleGuardRails, OracleSource, ExchangeStatus, SolvencyStatus, MarketStatus, ContractTier, AssetTier, TxParams, AddAmmConstituentMappingDatum, SwapReduceOnly, InitializeConstituentParams, ConstituentStatus, LPPoolAccount, TransferFeeAndPnlPoolDirection, MarketType } from './types';
|
|
11
11
|
import { BN } from './isomorphic/anchor';
|
|
12
12
|
import { VelocityClient } from './velocityClient';
|
|
13
13
|
import { JupiterClient, QuoteResponse } from './jupiter/jupiterClient';
|
|
@@ -182,6 +182,8 @@ export declare class AdminClient extends VelocityClient {
|
|
|
182
182
|
getUpdatePerpMarketContractTierIx(perpMarketIndex: number, contractTier: ContractTier): Promise<TransactionInstruction>;
|
|
183
183
|
updateExchangeStatus(exchangeStatus: ExchangeStatus): Promise<TransactionSignature>;
|
|
184
184
|
getUpdateExchangeStatusIx(exchangeStatus: ExchangeStatus): Promise<TransactionInstruction>;
|
|
185
|
+
updateSolvencyStatus(solvencyStatus: SolvencyStatus): Promise<TransactionSignature>;
|
|
186
|
+
getUpdateSolvencyStatusIx(solvencyStatus: SolvencyStatus): Promise<TransactionInstruction>;
|
|
185
187
|
updatePerpAuctionDuration(minDuration: BN | number): Promise<TransactionSignature>;
|
|
186
188
|
getUpdatePerpAuctionDurationIx(minDuration: BN | number): Promise<TransactionInstruction>;
|
|
187
189
|
updateSpotAuctionDuration(defaultAuctionDuration: number): Promise<TransactionSignature>;
|
|
@@ -1501,6 +1501,22 @@ class AdminClient extends velocityClient_1.VelocityClient {
|
|
|
1501
1501
|
},
|
|
1502
1502
|
});
|
|
1503
1503
|
}
|
|
1504
|
+
async updateSolvencyStatus(solvencyStatus) {
|
|
1505
|
+
const updateSolvencyStatusIx = await this.getUpdateSolvencyStatusIx(solvencyStatus);
|
|
1506
|
+
const tx = await this.buildTransaction(updateSolvencyStatusIx);
|
|
1507
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1508
|
+
return txSig;
|
|
1509
|
+
}
|
|
1510
|
+
async getUpdateSolvencyStatusIx(solvencyStatus) {
|
|
1511
|
+
return await this.program.instruction.updateSolvencyStatus(solvencyStatus, {
|
|
1512
|
+
accounts: {
|
|
1513
|
+
admin: this.isSubscribed
|
|
1514
|
+
? this.getStateAccount().coldAdmin
|
|
1515
|
+
: this.wallet.publicKey,
|
|
1516
|
+
state: await this.getStatePublicKey(),
|
|
1517
|
+
},
|
|
1518
|
+
});
|
|
1519
|
+
}
|
|
1504
1520
|
async updatePerpAuctionDuration(minDuration) {
|
|
1505
1521
|
const updatePerpAuctionDurationIx = await this.getUpdatePerpAuctionDurationIx(minDuration);
|
|
1506
1522
|
const tx = await this.buildTransaction(updatePerpAuctionDurationIx);
|
|
@@ -11074,6 +11074,35 @@ export type Velocity = {
|
|
|
11074
11074
|
}
|
|
11075
11075
|
];
|
|
11076
11076
|
},
|
|
11077
|
+
{
|
|
11078
|
+
"name": "updateSolvencyStatus";
|
|
11079
|
+
"discriminator": [
|
|
11080
|
+
81,
|
|
11081
|
+
136,
|
|
11082
|
+
15,
|
|
11083
|
+
6,
|
|
11084
|
+
24,
|
|
11085
|
+
165,
|
|
11086
|
+
44,
|
|
11087
|
+
133
|
|
11088
|
+
];
|
|
11089
|
+
"accounts": [
|
|
11090
|
+
{
|
|
11091
|
+
"name": "admin";
|
|
11092
|
+
"signer": true;
|
|
11093
|
+
},
|
|
11094
|
+
{
|
|
11095
|
+
"name": "state";
|
|
11096
|
+
"writable": true;
|
|
11097
|
+
}
|
|
11098
|
+
];
|
|
11099
|
+
"args": [
|
|
11100
|
+
{
|
|
11101
|
+
"name": "solvencyStatus";
|
|
11102
|
+
"type": "u8";
|
|
11103
|
+
}
|
|
11104
|
+
];
|
|
11105
|
+
},
|
|
11077
11106
|
{
|
|
11078
11107
|
"name": "updateSpecialUserStatus";
|
|
11079
11108
|
"discriminator": [
|
|
@@ -15978,6 +16007,16 @@ export type Velocity = {
|
|
|
15978
16007
|
"code": 6354;
|
|
15979
16008
|
"name": "insufficientProtocolFees";
|
|
15980
16009
|
"msg": "Insufficient protocol fees available to withdraw";
|
|
16010
|
+
},
|
|
16011
|
+
{
|
|
16012
|
+
"code": 6355;
|
|
16013
|
+
"name": "invalidNativeStateAccount";
|
|
16014
|
+
"msg": "Native dispatch: supplied state account is not the canonical Velocity state PDA";
|
|
16015
|
+
},
|
|
16016
|
+
{
|
|
16017
|
+
"code": 6356;
|
|
16018
|
+
"name": "invalidNativePerpMarketAccount";
|
|
16019
|
+
"msg": "Native dispatch: supplied market account is not a Velocity perp market";
|
|
15981
16020
|
}
|
|
15982
16021
|
];
|
|
15983
16022
|
"types": [
|
|
@@ -23213,6 +23252,16 @@ export type Velocity = {
|
|
|
23213
23252
|
"name": "lpPoolFeatureBitFlags";
|
|
23214
23253
|
"type": "u8";
|
|
23215
23254
|
},
|
|
23255
|
+
{
|
|
23256
|
+
"name": "solvencyStatus";
|
|
23257
|
+
"docs": [
|
|
23258
|
+
"Bitmask of `SolvencyStatus` flags. Gates internal solvency-repair flows",
|
|
23259
|
+
"(bankruptcy / pnl-deficit resolution) independently of `WithdrawPaused`,",
|
|
23260
|
+
"so user withdrawals can be halted while repair keeps running, or repair",
|
|
23261
|
+
"can be frozen on its own when an oracle is suspect. `0` = repair allowed."
|
|
23262
|
+
];
|
|
23263
|
+
"type": "u8";
|
|
23264
|
+
},
|
|
23216
23265
|
{
|
|
23217
23266
|
"name": "protocolFeeRecipientPerp";
|
|
23218
23267
|
"docs": [
|
|
@@ -23247,7 +23296,7 @@ export type Velocity = {
|
|
|
23247
23296
|
"type": {
|
|
23248
23297
|
"array": [
|
|
23249
23298
|
"u8",
|
|
23250
|
-
|
|
23299
|
+
271
|
|
23251
23300
|
];
|
|
23252
23301
|
};
|
|
23253
23302
|
}
|
|
@@ -11068,6 +11068,35 @@
|
|
|
11068
11068
|
}
|
|
11069
11069
|
]
|
|
11070
11070
|
},
|
|
11071
|
+
{
|
|
11072
|
+
"name": "update_solvency_status",
|
|
11073
|
+
"discriminator": [
|
|
11074
|
+
81,
|
|
11075
|
+
136,
|
|
11076
|
+
15,
|
|
11077
|
+
6,
|
|
11078
|
+
24,
|
|
11079
|
+
165,
|
|
11080
|
+
44,
|
|
11081
|
+
133
|
|
11082
|
+
],
|
|
11083
|
+
"accounts": [
|
|
11084
|
+
{
|
|
11085
|
+
"name": "admin",
|
|
11086
|
+
"signer": true
|
|
11087
|
+
},
|
|
11088
|
+
{
|
|
11089
|
+
"name": "state",
|
|
11090
|
+
"writable": true
|
|
11091
|
+
}
|
|
11092
|
+
],
|
|
11093
|
+
"args": [
|
|
11094
|
+
{
|
|
11095
|
+
"name": "solvency_status",
|
|
11096
|
+
"type": "u8"
|
|
11097
|
+
}
|
|
11098
|
+
]
|
|
11099
|
+
},
|
|
11071
11100
|
{
|
|
11072
11101
|
"name": "update_special_user_status",
|
|
11073
11102
|
"discriminator": [
|
|
@@ -15972,6 +16001,16 @@
|
|
|
15972
16001
|
"code": 6354,
|
|
15973
16002
|
"name": "InsufficientProtocolFees",
|
|
15974
16003
|
"msg": "Insufficient protocol fees available to withdraw"
|
|
16004
|
+
},
|
|
16005
|
+
{
|
|
16006
|
+
"code": 6355,
|
|
16007
|
+
"name": "InvalidNativeStateAccount",
|
|
16008
|
+
"msg": "Native dispatch: supplied state account is not the canonical Velocity state PDA"
|
|
16009
|
+
},
|
|
16010
|
+
{
|
|
16011
|
+
"code": 6356,
|
|
16012
|
+
"name": "InvalidNativePerpMarketAccount",
|
|
16013
|
+
"msg": "Native dispatch: supplied market account is not a Velocity perp market"
|
|
15975
16014
|
}
|
|
15976
16015
|
],
|
|
15977
16016
|
"types": [
|
|
@@ -23207,6 +23246,16 @@
|
|
|
23207
23246
|
"name": "lp_pool_feature_bit_flags",
|
|
23208
23247
|
"type": "u8"
|
|
23209
23248
|
},
|
|
23249
|
+
{
|
|
23250
|
+
"name": "solvency_status",
|
|
23251
|
+
"docs": [
|
|
23252
|
+
"Bitmask of `SolvencyStatus` flags. Gates internal solvency-repair flows",
|
|
23253
|
+
"(bankruptcy / pnl-deficit resolution) independently of `WithdrawPaused`,",
|
|
23254
|
+
"so user withdrawals can be halted while repair keeps running, or repair",
|
|
23255
|
+
"can be frozen on its own when an oracle is suspect. `0` = repair allowed."
|
|
23256
|
+
],
|
|
23257
|
+
"type": "u8"
|
|
23258
|
+
},
|
|
23210
23259
|
{
|
|
23211
23260
|
"name": "protocol_fee_recipient_perp",
|
|
23212
23261
|
"docs": [
|
|
@@ -23241,7 +23290,7 @@
|
|
|
23241
23290
|
"type": {
|
|
23242
23291
|
"array": [
|
|
23243
23292
|
"u8",
|
|
23244
|
-
|
|
23293
|
+
271
|
|
23245
23294
|
]
|
|
23246
23295
|
}
|
|
23247
23296
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PerpMarketAccount, PerpOperation, SpotMarketAccount, SpotOperation, StateAccount, InsuranceFundOperation, MarketConfigFlag } from '../types';
|
|
2
2
|
export declare function exchangePaused(state: StateAccount): boolean;
|
|
3
|
+
export declare function solvencyRepairPaused(state: StateAccount): boolean;
|
|
3
4
|
export declare function fillPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
4
5
|
export declare function ammPaused(state: StateAccount, market: PerpMarketAccount | SpotMarketAccount): boolean;
|
|
5
6
|
export declare function isOperationPaused(pausedOperations: number, operation: PerpOperation | SpotOperation | InsuranceFundOperation): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isFormulaicKUpdateDisabled = exports.isMarketConfigFlagSet = exports.isAmmDrawdownPause = exports.isOperationPaused = exports.ammPaused = exports.fillPaused = exports.exchangePaused = void 0;
|
|
3
|
+
exports.isFormulaicKUpdateDisabled = exports.isMarketConfigFlagSet = exports.isAmmDrawdownPause = exports.isOperationPaused = exports.ammPaused = exports.fillPaused = exports.solvencyRepairPaused = exports.exchangePaused = void 0;
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const anchor_1 = require("../isomorphic/anchor");
|
|
@@ -8,6 +8,13 @@ function exchangePaused(state) {
|
|
|
8
8
|
return state.exchangeStatus !== types_1.ExchangeStatus.ACTIVE;
|
|
9
9
|
}
|
|
10
10
|
exports.exchangePaused = exchangePaused;
|
|
11
|
+
// Mirror of the program's `State::solvency_repair_paused`. Gates the resolve
|
|
12
|
+
// bankruptcy / pnl-deficit instructions, independent of WITHDRAW_PAUSED.
|
|
13
|
+
function solvencyRepairPaused(state) {
|
|
14
|
+
return ((state.solvencyStatus & types_1.SolvencyStatus.SOLVENCY_REPAIR_PAUSED) ===
|
|
15
|
+
types_1.SolvencyStatus.SOLVENCY_REPAIR_PAUSED);
|
|
16
|
+
}
|
|
17
|
+
exports.solvencyRepairPaused = solvencyRepairPaused;
|
|
11
18
|
function fillPaused(state, market) {
|
|
12
19
|
if ((state.exchangeStatus & types_1.ExchangeStatus.FILL_PAUSED) ===
|
|
13
20
|
types_1.ExchangeStatus.FILL_PAUSED) {
|
|
@@ -26,5 +26,8 @@ export declare function calculateOrderBaseAssetAmount(order: Order, existingBase
|
|
|
26
26
|
* Returns:
|
|
27
27
|
* - BN size (>=0) if bounded
|
|
28
28
|
* - null if impossible (target < liabilityWeight) OR imfFactor == 0 (unbounded)
|
|
29
|
+
*
|
|
30
|
+
* Note: a market.maxOpenInterest of 0 means "no configured cap" and is treated
|
|
31
|
+
* as unlimited rather than a hard cap of 0.
|
|
29
32
|
*/
|
|
30
33
|
export declare function maxSizeForTargetLiabilityWeightBN(target: BN, imfFactor: BN, liabilityWeight: BN, market: PerpMarketAccount): BN | null;
|
|
@@ -181,6 +181,9 @@ exports.calculateOrderBaseAssetAmount = calculateOrderBaseAssetAmount;
|
|
|
181
181
|
* Returns:
|
|
182
182
|
* - BN size (>=0) if bounded
|
|
183
183
|
* - null if impossible (target < liabilityWeight) OR imfFactor == 0 (unbounded)
|
|
184
|
+
*
|
|
185
|
+
* Note: a market.maxOpenInterest of 0 means "no configured cap" and is treated
|
|
186
|
+
* as unlimited rather than a hard cap of 0.
|
|
184
187
|
*/
|
|
185
188
|
function maxSizeForTargetLiabilityWeightBN(target, imfFactor, liabilityWeight, market) {
|
|
186
189
|
if (target.lt(liabilityWeight))
|
|
@@ -212,9 +215,10 @@ function maxSizeForTargetLiabilityWeightBN(target, imfFactor, liabilityWeight, m
|
|
|
212
215
|
hi = mid.sub(numericConstants_1.ONE);
|
|
213
216
|
}
|
|
214
217
|
}
|
|
215
|
-
// cap at max OI
|
|
218
|
+
// cap at max OI. A maxOpenInterest of 0 means no configured cap (unlimited),
|
|
219
|
+
// matching the on-chain convention — do not treat it as a hard cap of 0.
|
|
216
220
|
const maxOpenInterest = market.maxOpenInterest;
|
|
217
|
-
if (lo.gt(maxOpenInterest)) {
|
|
221
|
+
if (!maxOpenInterest.isZero() && lo.gt(maxOpenInterest)) {
|
|
218
222
|
return maxOpenInterest;
|
|
219
223
|
}
|
|
220
224
|
return lo;
|
|
@@ -12,7 +12,7 @@ function calculateInitUserFee(stateAccount) {
|
|
|
12
12
|
const accountSpaceUtilization = stateAccount.numberOfSubAccounts
|
|
13
13
|
.addn(1)
|
|
14
14
|
.mul(numericConstants_1.PERCENTAGE_PRECISION)
|
|
15
|
-
.div(getMaxNumberOfSubAccounts(stateAccount));
|
|
15
|
+
.div(anchor_1.BN.max(getMaxNumberOfSubAccounts(stateAccount), new anchor_1.BN(1)));
|
|
16
16
|
if (accountSpaceUtilization.gt(targetUtilization)) {
|
|
17
17
|
return maxInitFee
|
|
18
18
|
.mul(accountSpaceUtilization.sub(targetUtilization))
|
package/lib/browser/memcmp.js
CHANGED
|
@@ -16,10 +16,31 @@ function getUserFilter() {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
exports.getUserFilter = getUserFilter;
|
|
19
|
+
/*
|
|
20
|
+
* Byte offsets of the trailing scalar flags in the `User` account.
|
|
21
|
+
*
|
|
22
|
+
* These MUST match the on-chain `User` layout decoded in `decode/user.ts`. The
|
|
23
|
+
* current Velocity layout is 4496 bytes, with the tail block laid out as
|
|
24
|
+
* consecutive single bytes:
|
|
25
|
+
* status(4468) isMarginTradingEnabled(4469) idle(4470) openOrders(4471)
|
|
26
|
+
* hasOpenOrder(4472) openAuctions(4473) hasOpenAuction(4474) poolId(4475)
|
|
27
|
+
* specialUserStatus(4476)
|
|
28
|
+
*
|
|
29
|
+
* NOTE: these were previously hardcoded to the older (4376-byte) layout
|
|
30
|
+
* (idle@4350, hasOpenOrder@4352, ...). After Velocity added fields to
|
|
31
|
+
* `PerpPosition`, the account grew by 120 bytes and these flags shifted, but
|
|
32
|
+
* the filters were not updated — so `getUserWithOrderFilter()` matched zero
|
|
33
|
+
* accounts and the DLOB order book never populated. Keep these in sync with
|
|
34
|
+
* `decode/user.ts` if the `User` layout changes again.
|
|
35
|
+
*/
|
|
36
|
+
const USER_IDLE_OFFSET = 4470;
|
|
37
|
+
const USER_HAS_OPEN_ORDER_OFFSET = 4472;
|
|
38
|
+
const USER_HAS_OPEN_AUCTION_OFFSET = 4474;
|
|
39
|
+
const USER_POOL_ID_OFFSET = 4475;
|
|
19
40
|
function getNonIdleUserFilter() {
|
|
20
41
|
return {
|
|
21
42
|
memcmp: {
|
|
22
|
-
offset:
|
|
43
|
+
offset: USER_IDLE_OFFSET,
|
|
23
44
|
bytes: bs58_1.default.encode(Uint8Array.from([0])),
|
|
24
45
|
},
|
|
25
46
|
};
|
|
@@ -28,7 +49,7 @@ exports.getNonIdleUserFilter = getNonIdleUserFilter;
|
|
|
28
49
|
function getUserWithOrderFilter() {
|
|
29
50
|
return {
|
|
30
51
|
memcmp: {
|
|
31
|
-
offset:
|
|
52
|
+
offset: USER_HAS_OPEN_ORDER_OFFSET,
|
|
32
53
|
bytes: bs58_1.default.encode(Uint8Array.from([1])),
|
|
33
54
|
},
|
|
34
55
|
};
|
|
@@ -37,7 +58,7 @@ exports.getUserWithOrderFilter = getUserWithOrderFilter;
|
|
|
37
58
|
function getUserWithoutOrderFilter() {
|
|
38
59
|
return {
|
|
39
60
|
memcmp: {
|
|
40
|
-
offset:
|
|
61
|
+
offset: USER_HAS_OPEN_ORDER_OFFSET,
|
|
41
62
|
bytes: bs58_1.default.encode(Uint8Array.from([0])),
|
|
42
63
|
},
|
|
43
64
|
};
|
|
@@ -46,7 +67,7 @@ exports.getUserWithoutOrderFilter = getUserWithoutOrderFilter;
|
|
|
46
67
|
function getUserWithAuctionFilter() {
|
|
47
68
|
return {
|
|
48
69
|
memcmp: {
|
|
49
|
-
offset:
|
|
70
|
+
offset: USER_HAS_OPEN_AUCTION_OFFSET,
|
|
50
71
|
bytes: bs58_1.default.encode(Uint8Array.from([1])),
|
|
51
72
|
},
|
|
52
73
|
};
|
|
@@ -64,7 +85,7 @@ exports.getUserWithName = getUserWithName;
|
|
|
64
85
|
function getUsersWithPoolId(poolId) {
|
|
65
86
|
return {
|
|
66
87
|
memcmp: {
|
|
67
|
-
offset:
|
|
88
|
+
offset: USER_POOL_ID_OFFSET,
|
|
68
89
|
bytes: bs58_1.default.encode(Uint8Array.from([poolId])),
|
|
69
90
|
},
|
|
70
91
|
};
|
|
@@ -13,6 +13,15 @@ const user_1 = require("../decode/user");
|
|
|
13
13
|
const grpcSubscription_1 = require("./grpcSubscription");
|
|
14
14
|
const orders_1 = require("../math/orders");
|
|
15
15
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
16
|
+
/*
|
|
17
|
+
* Byte offset of `lastActiveSlot` (u64) in the `User` account, used here to
|
|
18
|
+
* cheaply detect stale updates without fully decoding the buffer. Must match
|
|
19
|
+
* the on-chain `User` layout (see `decode/user.ts`). The previous value (4328)
|
|
20
|
+
* was for the older 4376-byte layout; the current Velocity layout is 4496
|
|
21
|
+
* bytes, shifting this field +120 bytes. With the wrong offset this read 8
|
|
22
|
+
* zero-padding bytes, so the staleness guard rejected every post-load update.
|
|
23
|
+
*/
|
|
24
|
+
const USER_LAST_ACTIVE_SLOT_OFFSET = 4448;
|
|
16
25
|
class OrderSubscriber {
|
|
17
26
|
constructor(config) {
|
|
18
27
|
var _a, _b, _c, _d, _e;
|
|
@@ -121,7 +130,7 @@ class OrderSubscriber {
|
|
|
121
130
|
if (dataType === 'raw') {
|
|
122
131
|
// @ts-ignore
|
|
123
132
|
const buffer = buffer_1.Buffer.from(data[0], data[1]);
|
|
124
|
-
const newLastActiveSlot = new anchor_1.BN(buffer.subarray(
|
|
133
|
+
const newLastActiveSlot = new anchor_1.BN(buffer.subarray(USER_LAST_ACTIVE_SLOT_OFFSET, USER_LAST_ACTIVE_SLOT_OFFSET + 8), undefined, 'le');
|
|
125
134
|
if (slotAndUserAccount &&
|
|
126
135
|
slotAndUserAccount.userAccount.lastActiveSlot.gt(newLastActiveSlot)) {
|
|
127
136
|
return;
|
|
@@ -130,7 +139,7 @@ class OrderSubscriber {
|
|
|
130
139
|
}
|
|
131
140
|
else if (dataType === 'buffer') {
|
|
132
141
|
const buffer = data;
|
|
133
|
-
const newLastActiveSlot = new anchor_1.BN(buffer.subarray(
|
|
142
|
+
const newLastActiveSlot = new anchor_1.BN(buffer.subarray(USER_LAST_ACTIVE_SLOT_OFFSET, USER_LAST_ACTIVE_SLOT_OFFSET + 8), undefined, 'le');
|
|
134
143
|
if (slotAndUserAccount &&
|
|
135
144
|
slotAndUserAccount.userAccount.lastActiveSlot.gt(newLastActiveSlot)) {
|
|
136
145
|
return;
|
|
@@ -71,8 +71,8 @@ class SwiftOrderSubscriber {
|
|
|
71
71
|
this.onOrder = onOrder;
|
|
72
72
|
const env = this.config.velocityEnv;
|
|
73
73
|
const endpoint = (_a = this.config.endpoint) !== null && _a !== void 0 ? _a : (env === 'devnet'
|
|
74
|
-
? 'wss://master.
|
|
75
|
-
: 'wss://swift.
|
|
74
|
+
? 'wss://swift.master.velocity.exchange/ws'
|
|
75
|
+
: 'wss://swift.velocity.exchange/ws');
|
|
76
76
|
const ws = new ws_1.default(endpoint + '?pubkey=' + this.config.keypair.publicKey.toBase58());
|
|
77
77
|
this.ws = ws;
|
|
78
78
|
ws.on('open', async () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as anchor from './isomorphic/
|
|
2
|
-
import { AnchorProvider, Program } from './isomorphic/
|
|
1
|
+
import * as anchor from './isomorphic/anchor';
|
|
2
|
+
import { AnchorProvider, Program } from './isomorphic/anchor';
|
|
3
3
|
import { Account } from '@solana/spl-token';
|
|
4
4
|
import { ConfirmOptions, Connection, PublicKey, TransactionInstruction, TransactionSignature } from '@solana/web3.js';
|
|
5
5
|
import { IWallet } from './types';
|