@velocity-exchange/sdk 0.2.5 → 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.
Files changed (61) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +3 -3
  3. package/lib/browser/adminClient.d.ts +3 -1
  4. package/lib/browser/adminClient.js +16 -0
  5. package/lib/browser/idl/velocity.d.ts +50 -1
  6. package/lib/browser/idl/velocity.json +50 -1
  7. package/lib/browser/math/exchangeStatus.d.ts +1 -0
  8. package/lib/browser/math/exchangeStatus.js +8 -1
  9. package/lib/browser/math/orders.d.ts +3 -0
  10. package/lib/browser/math/orders.js +6 -2
  11. package/lib/browser/math/state.js +1 -1
  12. package/lib/browser/memcmp.js +26 -5
  13. package/lib/browser/orderSubscriber/OrderSubscriber.js +11 -2
  14. package/lib/browser/swift/swiftOrderSubscriber.js +2 -2
  15. package/lib/browser/tokenFaucet.d.ts +2 -2
  16. package/lib/browser/tokenFaucet.js +11 -4
  17. package/lib/browser/types.d.ts +5 -0
  18. package/lib/browser/types.js +9 -2
  19. package/lib/browser/velocityClient.d.ts +1 -1
  20. package/lib/browser/velocityClient.js +16 -4
  21. package/lib/node/adminClient.d.ts +3 -1
  22. package/lib/node/adminClient.d.ts.map +1 -1
  23. package/lib/node/adminClient.js +16 -0
  24. package/lib/node/idl/velocity.d.ts +50 -1
  25. package/lib/node/idl/velocity.d.ts.map +1 -1
  26. package/lib/node/idl/velocity.json +50 -1
  27. package/lib/node/math/exchangeStatus.d.ts +1 -0
  28. package/lib/node/math/exchangeStatus.d.ts.map +1 -1
  29. package/lib/node/math/exchangeStatus.js +8 -1
  30. package/lib/node/math/orders.d.ts +3 -0
  31. package/lib/node/math/orders.d.ts.map +1 -1
  32. package/lib/node/math/orders.js +6 -2
  33. package/lib/node/math/state.js +1 -1
  34. package/lib/node/memcmp.d.ts.map +1 -1
  35. package/lib/node/memcmp.js +26 -5
  36. package/lib/node/orderSubscriber/OrderSubscriber.d.ts.map +1 -1
  37. package/lib/node/orderSubscriber/OrderSubscriber.js +11 -2
  38. package/lib/node/swift/swiftOrderSubscriber.js +2 -2
  39. package/lib/node/tokenFaucet.d.ts +2 -2
  40. package/lib/node/tokenFaucet.d.ts.map +1 -1
  41. package/lib/node/tokenFaucet.js +11 -4
  42. package/lib/node/types.d.ts +5 -0
  43. package/lib/node/types.d.ts.map +1 -1
  44. package/lib/node/types.js +9 -2
  45. package/lib/node/velocityClient.d.ts +1 -1
  46. package/lib/node/velocityClient.d.ts.map +1 -1
  47. package/lib/node/velocityClient.js +16 -4
  48. package/package.json +1 -1
  49. package/src/adminClient.ts +28 -0
  50. package/src/idl/velocity.json +50 -1
  51. package/src/idl/velocity.ts +50 -1
  52. package/src/math/exchangeStatus.ts +10 -0
  53. package/src/math/orders.ts +6 -2
  54. package/src/math/state.ts +1 -1
  55. package/src/memcmp.ts +27 -5
  56. package/src/orderSubscriber/OrderSubscriber.ts +18 -2
  57. package/src/swift/swiftOrderSubscriber.ts +2 -2
  58. package/src/tokenFaucet.ts +10 -7
  59. package/src/types.ts +8 -0
  60. package/src/velocityClient.ts +17 -5
  61. package/tests/dlob/helpers.ts +1 -0
@@ -19,6 +19,16 @@ import { grpcSubscription } from './grpcSubscription';
19
19
  import { calculateOrderBaseAssetAmount } from '../math/orders';
20
20
  import { ZERO } from '../constants/numericConstants';
21
21
 
22
+ /*
23
+ * Byte offset of `lastActiveSlot` (u64) in the `User` account, used here to
24
+ * cheaply detect stale updates without fully decoding the buffer. Must match
25
+ * the on-chain `User` layout (see `decode/user.ts`). The previous value (4328)
26
+ * was for the older 4376-byte layout; the current Velocity layout is 4496
27
+ * bytes, shifting this field +120 bytes. With the wrong offset this read 8
28
+ * zero-padding bytes, so the staleness guard rejected every post-load update.
29
+ */
30
+ const USER_LAST_ACTIVE_SLOT_OFFSET = 4448;
31
+
22
32
  export class OrderSubscriber {
23
33
  velocityClient: VelocityClient;
24
34
  usersAccounts = new Map<string, { slot: number; userAccount: UserAccount }>();
@@ -176,7 +186,10 @@ export class OrderSubscriber {
176
186
  const buffer = Buffer.from(data[0], data[1]);
177
187
 
178
188
  const newLastActiveSlot = new BN(
179
- buffer.subarray(4328, 4328 + 8),
189
+ buffer.subarray(
190
+ USER_LAST_ACTIVE_SLOT_OFFSET,
191
+ USER_LAST_ACTIVE_SLOT_OFFSET + 8
192
+ ),
180
193
  undefined,
181
194
  'le'
182
195
  );
@@ -191,7 +204,10 @@ export class OrderSubscriber {
191
204
  } else if (dataType === 'buffer') {
192
205
  const buffer: Buffer = data as Buffer;
193
206
  const newLastActiveSlot = new BN(
194
- buffer.subarray(4328, 4328 + 8),
207
+ buffer.subarray(
208
+ USER_LAST_ACTIVE_SLOT_OFFSET,
209
+ USER_LAST_ACTIVE_SLOT_OFFSET + 8
210
+ ),
195
211
  undefined,
196
212
  'le'
197
213
  );
@@ -161,8 +161,8 @@ export class SwiftOrderSubscriber {
161
161
  const endpoint =
162
162
  this.config.endpoint ??
163
163
  (env === 'devnet'
164
- ? 'wss://master.swift.drift.trade/ws'
165
- : 'wss://swift.drift.trade/ws');
164
+ ? 'wss://swift.master.velocity.exchange/ws'
165
+ : 'wss://swift.velocity.exchange/ws');
166
166
  const ws = new WebSocket(
167
167
  endpoint + '?pubkey=' + this.config.keypair.publicKey.toBase58()
168
168
  );
@@ -1,5 +1,5 @@
1
- import * as anchor from './isomorphic/anchor29';
2
- import { AnchorProvider, Idl, Program } from './isomorphic/anchor29';
1
+ import * as anchor from './isomorphic/anchor';
2
+ import { AnchorProvider, Idl, Program } from './isomorphic/anchor';
3
3
  import {
4
4
  TOKEN_PROGRAM_ID,
5
5
  Account,
@@ -51,11 +51,14 @@ export class TokenFaucet {
51
51
  this.opts
52
52
  );
53
53
  this.provider = provider;
54
- this.program = new Program(
55
- tokenFaucet as unknown as Idl,
56
- programId,
57
- provider
58
- );
54
+ // Anchor (>= 0.30) reads the program id from `idl.address` rather than a
55
+ // constructor argument. Override it with the caller-provided `programId`
56
+ // so PDAs and instructions target the intended program.
57
+ const idl = {
58
+ ...(tokenFaucet as unknown as Idl),
59
+ address: programId.toBase58(),
60
+ } as Idl;
61
+ this.program = new Program(idl, provider);
59
62
  this.mint = mint;
60
63
  }
61
64
 
package/src/types.ts CHANGED
@@ -39,6 +39,13 @@ export enum ExchangeStatus {
39
39
  PAUSED = 255,
40
40
  }
41
41
 
42
+ // Mirror of the Rust `SolvencyStatus` bitflag (State.solvencyStatus). Gates
43
+ // internal solvency-repair flows independently of ExchangeStatus.WITHDRAW_PAUSED.
44
+ export enum SolvencyStatus {
45
+ ACTIVE = 0,
46
+ SOLVENCY_REPAIR_PAUSED = 1,
47
+ }
48
+
42
49
  export enum FeatureBitFlags {
43
50
  MM_ORACLE_UPDATE = 1,
44
51
  MEDIAN_TRIGGER_PRICE = 2,
@@ -771,6 +778,7 @@ export type StateAccount = {
771
778
  maxInitializeUserFee: number;
772
779
  featureBitFlags: number;
773
780
  lpPoolFeatureBitFlags: number;
781
+ solvencyStatus: number;
774
782
  };
775
783
 
776
784
  export type PerpMarketAccount = {
@@ -2304,7 +2304,7 @@ export class VelocityClient {
2304
2304
  subAccountId = subAccountId ?? this.activeSubAccountId;
2305
2305
  authority = authority ?? this.authority;
2306
2306
  if (subAccountId === undefined || authority === undefined) {
2307
- throw new Error('Subaccount ID and authority are required');
2307
+ return false;
2308
2308
  }
2309
2309
  const userMapKey = this.getUserMapKey(subAccountId, authority);
2310
2310
 
@@ -10329,7 +10329,11 @@ export class VelocityClient {
10329
10329
  );
10330
10330
 
10331
10331
  const tx = await this.buildTransaction(updateMmOracleIx, {
10332
- computeUnits: 1000,
10332
+ // Headroom for the native handler's owner + discriminator validation
10333
+ // of the state + perp-market accounts (was 1000 when it bytemuck-cast
10334
+ // the market without any checks). Measured ~1.3k CU; 2000 leaves
10335
+ // margin for the production-only signer check.
10336
+ computeUnits: 2000,
10333
10337
  computeUnitsPrice: 0,
10334
10338
  });
10335
10339
  const { txSig } = await this.sendTransaction(tx, [], this.opts);
@@ -10337,16 +10341,19 @@ export class VelocityClient {
10337
10341
  return txSig;
10338
10342
  }
10339
10343
 
10340
- public getUpdateAmmSpreadAdjustmentNativeIx(
10344
+ public async getUpdateAmmSpreadAdjustmentNativeIx(
10341
10345
  marketIndex: number,
10342
10346
  ammSpreadAdjustment: number // i8
10343
- ): TransactionInstruction {
10347
+ ): Promise<TransactionInstruction> {
10344
10348
  const discriminatorBuffer = createNativeInstructionDiscriminatorBuffer(1);
10345
10349
  const data = Buffer.alloc(discriminatorBuffer.length + 4);
10346
10350
  data.set(discriminatorBuffer, 0);
10347
10351
  data.writeInt8(ammSpreadAdjustment, 5); // next byte
10348
10352
 
10349
- // Build the instruction manually
10353
+ // Build the instruction manually. The native handler re-establishes the
10354
+ // account guarantees Anchor would normally provide: it loads `state` as
10355
+ // the program-owned State account and authenticates the signer against
10356
+ // `state.hotAmmSpreadAdjust`, so the state account is required at index 2.
10350
10357
  return new TransactionInstruction({
10351
10358
  programId: this.program.programId,
10352
10359
  keys: [
@@ -10360,6 +10367,11 @@ export class VelocityClient {
10360
10367
  isWritable: false,
10361
10368
  isSigner: true,
10362
10369
  },
10370
+ {
10371
+ pubkey: await this.getStatePublicKey(),
10372
+ isWritable: false,
10373
+ isSigner: false,
10374
+ },
10363
10375
  ],
10364
10376
  data,
10365
10377
  });
@@ -560,6 +560,7 @@ export const mockStateAccount: StateAccount = {
560
560
  protocolFeeRecipientSpot: PublicKey.default,
561
561
  featureBitFlags: 0,
562
562
  lpPoolFeatureBitFlags: 0,
563
+ solvencyStatus: 0,
563
564
  defaultMarketOrderTimeInForce: 0,
564
565
  defaultSpotAuctionDuration: 0,
565
566
  discountMint: PublicKey.default,