@velocity-exchange/sdk 0.2.3 → 0.2.5

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 (54) hide show
  1. package/CHANGELOG.md +23 -3
  2. package/README.md +5 -5
  3. package/lib/browser/accounts/grpcMultiAccountSubscriber.d.ts +0 -1
  4. package/lib/browser/accounts/grpcMultiAccountSubscriber.js +2 -7
  5. package/lib/browser/accounts/grpcMultiUserAccountSubscriber.js +3 -0
  6. package/lib/browser/accounts/webSocketAccountSubscriberV2.js +1 -2
  7. package/lib/browser/accounts/websocketProgramUserAccountSubscriber.js +3 -0
  8. package/lib/browser/config.js +1 -1
  9. package/lib/browser/constants/spotMarkets.js +1 -1
  10. package/lib/browser/math/liquidation.d.ts +14 -0
  11. package/lib/browser/math/liquidation.js +14 -0
  12. package/lib/browser/types.d.ts +75 -9
  13. package/lib/browser/user.d.ts +22 -6
  14. package/lib/browser/user.js +24 -8
  15. package/lib/browser/userMap/userMap.js +5 -1
  16. package/lib/browser/velocityClient.d.ts +0 -2
  17. package/lib/browser/velocityClient.js +0 -18
  18. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts +0 -1
  19. package/lib/node/accounts/grpcMultiAccountSubscriber.d.ts.map +1 -1
  20. package/lib/node/accounts/grpcMultiAccountSubscriber.js +2 -7
  21. package/lib/node/accounts/grpcMultiUserAccountSubscriber.d.ts.map +1 -1
  22. package/lib/node/accounts/grpcMultiUserAccountSubscriber.js +3 -0
  23. package/lib/node/accounts/webSocketAccountSubscriberV2.d.ts.map +1 -1
  24. package/lib/node/accounts/webSocketAccountSubscriberV2.js +1 -2
  25. package/lib/node/accounts/websocketProgramUserAccountSubscriber.d.ts.map +1 -1
  26. package/lib/node/accounts/websocketProgramUserAccountSubscriber.js +3 -0
  27. package/lib/node/config.js +1 -1
  28. package/lib/node/constants/spotMarkets.js +1 -1
  29. package/lib/node/math/liquidation.d.ts +14 -0
  30. package/lib/node/math/liquidation.d.ts.map +1 -1
  31. package/lib/node/math/liquidation.js +14 -0
  32. package/lib/node/types.d.ts +75 -9
  33. package/lib/node/types.d.ts.map +1 -1
  34. package/lib/node/user.d.ts +22 -6
  35. package/lib/node/user.d.ts.map +1 -1
  36. package/lib/node/user.js +24 -8
  37. package/lib/node/userMap/userMap.d.ts.map +1 -1
  38. package/lib/node/userMap/userMap.js +5 -1
  39. package/lib/node/velocityClient.d.ts +0 -2
  40. package/lib/node/velocityClient.d.ts.map +1 -1
  41. package/lib/node/velocityClient.js +0 -18
  42. package/package.json +2 -2
  43. package/src/accounts/grpcMultiAccountSubscriber.ts +2 -10
  44. package/src/accounts/grpcMultiUserAccountSubscriber.ts +5 -0
  45. package/src/accounts/webSocketAccountSubscriberV2.ts +1 -5
  46. package/src/accounts/websocketProgramUserAccountSubscriber.ts +5 -0
  47. package/src/config.ts +1 -1
  48. package/src/constants/spotMarkets.ts +1 -1
  49. package/src/math/liquidation.ts +14 -0
  50. package/src/types.ts +82 -9
  51. package/src/user.ts +24 -8
  52. package/src/userMap/userMap.ts +5 -1
  53. package/src/velocityClient.ts +0 -31
  54. package/tests/dlob/helpers.ts +24 -4
package/CHANGELOG.md CHANGED
@@ -1,19 +1,39 @@
1
1
  # @velocity-exchange/sdk
2
2
 
3
+ ## 0.2.5
4
+
5
+ ### Patch Changes
6
+
7
+ - [#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
8
+ misleading error message. `getUserAccountAndSlot()` now throws `NotSubscribedError`
9
+ when called before `subscribe()` on the gRPC-multi and WebSocket-program subscribers
10
+ too (the WebSocket and polling subscribers already did) — so `User.getUserAccount()`
11
+ uniformly throws when not subscribed and returns `undefined` only when subscribed but
12
+ the account was not found on chain. `getUserAccountOrThrow()` /
13
+ `getUserAccountAndSlotOrThrow()` now throw `User account not found: <pubkey>` (was
14
+ `User account not loaded`), since after `subscribe()` resolves a missing account means
15
+ "not found", not "still loading".
16
+
17
+ ## 0.2.4
18
+
19
+ ### Patch Changes
20
+
21
+ - [#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
22
+
3
23
  ## 0.2.3
4
24
 
5
25
  ### Patch Changes
6
26
 
7
- - [#100](https://github.com/drift-labs/protocol-v2-shadow/pull/100) [`ae78769`](https://github.com/drift-labs/protocol-v2-shadow/commit/ae78769ef58355202c030435c2796ef045fe30a0) Thanks [@ChesterSim](https://github.com/ChesterSim)! - add back ForwardOnlyTxSender and calculateMaxRemainingDeposit
27
+ - [#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
8
28
 
9
29
  ## 0.2.2
10
30
 
11
31
  ### Patch Changes
12
32
 
13
- - [#97](https://github.com/drift-labs/protocol-v2-shadow/pull/97) [`022a949`](https://github.com/drift-labs/protocol-v2-shadow/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.
33
+ - [#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.
14
34
 
15
35
  ## 0.2.1
16
36
 
17
37
  ### Patch Changes
18
38
 
19
- - [`4fd7462`](https://github.com/drift-labs/protocol-v2-shadow/commit/4fd7462bfa3c55e31e3457b1b65f519cf052a6fa) Thanks [@ChewingGlass](https://github.com/ChewingGlass)! - Testing new changelog based package publishing flow
39
+ - [`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/drift-labs/protocol-v2-shadow/master/assets/velocity-logo.svg" />
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://drift-labs.github.io/protocol-v2/sdk/"><img alt="Docs" src="https://img.shields.io/badge/docs-tutorials-blueviolet" /></a>
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://drift-labs.github.io/v2-teacher/)
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://drift-labs.github.io/protocol-v2/sdk/)
28
+ - [Typescript API docs](https://velocity-exchange.github.io/protocol-v2/sdk/)
29
29
  - JSDoc automated documentation for the Velocity v2 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://drift-labs.github.io/v2-teacher/).
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
 
@@ -34,5 +34,4 @@ export declare class grpcMultiAccountSubscriber<T, U = undefined> {
34
34
  removeAccounts(accounts: PublicKey[]): Promise<void>;
35
35
  unsubscribe(): Promise<void>;
36
36
  private setTimeout;
37
- private capitalize;
38
37
  }
@@ -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.capitalize(this.accountName), newBuffer);
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.capitalize(this.accountName), buffer);
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((0, utils_1.capitalize)(this.accountName), buffer);
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
  }
@@ -22,7 +22,7 @@ exports.configs = {
22
22
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
23
23
  VELOCITY_PROGRAM_ID: exports.VELOCITY_DEVNET_PROGRAM_ID,
24
24
  JIT_PROXY_PROGRAM_ID: 'J1TnP8zvVxbtF5KFp5xRmWuvG9McnhzmBd9XGfCyuxFP',
25
- QUOTE_MINT_ADDRESS: '8FfvSRKMZRDHrCBy142XMUXrKEkXnxDQ4YmJv7xbAw8Q',
25
+ QUOTE_MINT_ADDRESS: 'GqmEqYsy8EyvofDpmtFxK8zhYrgWgNokAtYoduQdL7v6',
26
26
  V2_ALPHA_TICKET_MINT_ADDRESS: 'DeEiGWfCMP9psnLGkxGrBBMEAW5Jv8bBGMN8DCtFRCyB',
27
27
  PERP_MARKETS: perpMarkets_1.DevnetPerpMarkets,
28
28
  SPOT_MARKETS: spotMarkets_1.DevnetSpotMarkets,
@@ -15,7 +15,7 @@ exports.DevnetSpotMarkets = [
15
15
  poolId: 0,
16
16
  oracle: new web3_js_1.PublicKey('Dai8hT1YRBBm5rBSJUSKcdR11psM55LVAkshbypfC4k4'),
17
17
  oracleSource: types_1.OracleSource.PYTH_LAZER_STABLE_COIN,
18
- mint: new web3_js_1.PublicKey('8FfvSRKMZRDHrCBy142XMUXrKEkXnxDQ4YmJv7xbAw8Q'),
18
+ mint: new web3_js_1.PublicKey('GqmEqYsy8EyvofDpmtFxK8zhYrgWgNokAtYoduQdL7v6'),
19
19
  precision: new anchor_1.BN(10).pow(numericConstants_1.SIX),
20
20
  precisionExp: numericConstants_1.SIX,
21
21
  pythLazerId: 8,
@@ -1,5 +1,19 @@
1
1
  import { BN } from '../isomorphic/anchor';
2
+ /**
3
+ * @param ifLiquidationFee Since PR#75 the program sizes liquidations against the
4
+ * COMBINED insurance-fund + protocol liquidation fee budget:
5
+ * `market.ifLiquidationFee + market.protocolLiquidationFee` (split IF-first
6
+ * on-chain). Pass that sum here to match on-chain sizing; passing
7
+ * `market.ifLiquidationFee` alone under-sizes the estimate.
8
+ */
2
9
  export declare function calculateBaseAssetAmountToCoverMarginShortage(marginShortage: BN, marginRatio: number, liquidationFee: number, ifLiquidationFee: number, oraclePrice: BN, quoteOraclePrice: BN): BN | undefined;
10
+ /**
11
+ * @param ifLiquidationFee Since PR#75 the program sizes liquidations against the
12
+ * COMBINED insurance-fund + protocol liquidation fee budget:
13
+ * `market.ifLiquidationFee + market.protocolLiquidationFee` (split IF-first
14
+ * on-chain). Pass that sum here to match on-chain sizing; passing
15
+ * `market.ifLiquidationFee` alone under-sizes the estimate.
16
+ */
3
17
  export declare function calculateLiabilityTransferToCoverMarginShortage(marginShortage: BN, assetWeight: number, assetLiquidationMultiplier: number, liabilityWeight: number, liabilityLiquidationMultiplier: number, liabilityDecimals: number, liabilityPrice: BN, ifLiquidationFee: number): BN | undefined;
4
18
  export declare function calculateAssetTransferForLiabilityTransfer(assetAmount: BN, assetLiquidationMultiplier: number, assetDecimals: number, assetPrice: BN, liabilityAmount: BN, liabilityLiquidationMultiplier: number, liabilityDecimals: number, liabilityPrice: BN): BN | undefined;
5
19
  export declare function calculateMaxPctToLiquidate(userLastActiveSlot: BN, userLiquidationMarginFreed: BN, marginShortage: BN, slot: BN, initialPctToLiquidate: BN, liquidationDuration: BN): BN;
@@ -3,6 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getMarginShortage = exports.calculateMaxPctToLiquidate = exports.calculateAssetTransferForLiabilityTransfer = exports.calculateLiabilityTransferToCoverMarginShortage = exports.calculateBaseAssetAmountToCoverMarginShortage = void 0;
4
4
  const anchor_1 = require("../isomorphic/anchor");
5
5
  const numericConstants_1 = require("../constants/numericConstants");
6
+ /**
7
+ * @param ifLiquidationFee Since PR#75 the program sizes liquidations against the
8
+ * COMBINED insurance-fund + protocol liquidation fee budget:
9
+ * `market.ifLiquidationFee + market.protocolLiquidationFee` (split IF-first
10
+ * on-chain). Pass that sum here to match on-chain sizing; passing
11
+ * `market.ifLiquidationFee` alone under-sizes the estimate.
12
+ */
6
13
  function calculateBaseAssetAmountToCoverMarginShortage(marginShortage, marginRatio, liquidationFee, ifLiquidationFee, oraclePrice, quoteOraclePrice) {
7
14
  const marginRatioBN = new anchor_1.BN(marginRatio)
8
15
  .mul(numericConstants_1.LIQUIDATION_FEE_PRECISION)
@@ -20,6 +27,13 @@ function calculateBaseAssetAmountToCoverMarginShortage(marginShortage, marginRat
20
27
  .sub(oraclePrice.mul(new anchor_1.BN(ifLiquidationFee)).div(numericConstants_1.LIQUIDATION_FEE_PRECISION)));
21
28
  }
22
29
  exports.calculateBaseAssetAmountToCoverMarginShortage = calculateBaseAssetAmountToCoverMarginShortage;
30
+ /**
31
+ * @param ifLiquidationFee Since PR#75 the program sizes liquidations against the
32
+ * COMBINED insurance-fund + protocol liquidation fee budget:
33
+ * `market.ifLiquidationFee + market.protocolLiquidationFee` (split IF-first
34
+ * on-chain). Pass that sum here to match on-chain sizing; passing
35
+ * `market.ifLiquidationFee` alone under-sizes the estimate.
36
+ */
23
37
  function calculateLiabilityTransferToCoverMarginShortage(marginShortage, assetWeight, assetLiquidationMultiplier, liabilityWeight, liabilityLiquidationMultiplier, liabilityDecimals, liabilityPrice, ifLiquidationFee) {
24
38
  if (assetWeight >= liabilityWeight) {
25
39
  // undefined is max
@@ -464,6 +464,8 @@ export type DepositRecord = {
464
464
  depositRecordId: BN;
465
465
  explanation: DepositExplanation;
466
466
  transferUser?: PublicKey;
467
+ signer?: PublicKey;
468
+ userTokenAmountAfter: BN;
467
469
  };
468
470
  export type SpotInterestRecord = {
469
471
  ts: BN;
@@ -551,13 +553,14 @@ export type LiquidationRecord = {
551
553
  marginFreed: BN;
552
554
  liquidationId: number;
553
555
  bankrupt: boolean;
554
- canceledOrderIds: BN[];
556
+ canceledOrderIds: number[];
555
557
  liquidatePerp: LiquidatePerpRecord;
556
558
  liquidateSpot: LiquidateSpotRecord;
557
559
  liquidateBorrowForPerpPnl: LiquidateBorrowForPerpPnlRecord;
558
560
  liquidatePerpPnlForDeposit: LiquidatePerpPnlForDepositRecord;
559
561
  perpBankruptcy: PerpBankruptcyRecord;
560
562
  spotBankruptcy: SpotBankruptcyRecord;
563
+ bitFlags: number;
561
564
  };
562
565
  export declare class LiquidationType {
563
566
  static readonly LIQUIDATE_PERP: {
@@ -584,11 +587,12 @@ export type LiquidatePerpRecord = {
584
587
  oraclePrice: BN;
585
588
  baseAssetAmount: BN;
586
589
  quoteAssetAmount: BN;
587
- userOrderId: BN;
588
- liquidatorOrderId: BN;
590
+ userOrderId: number;
591
+ liquidatorOrderId: number;
589
592
  fillRecordId: BN;
590
593
  liquidatorFee: BN;
591
594
  ifFee: BN;
595
+ protocolFee: BN;
592
596
  };
593
597
  export type LiquidateSpotRecord = {
594
598
  assetMarketIndex: number;
@@ -598,6 +602,7 @@ export type LiquidateSpotRecord = {
598
602
  liabilityPrice: BN;
599
603
  liabilityTransfer: BN;
600
604
  ifFee: BN;
605
+ protocolFee: BN;
601
606
  };
602
607
  export type LiquidateBorrowForPerpPnlRecord = {
603
608
  perpMarketIndex: number;
@@ -691,6 +696,9 @@ export type OrderActionRecord = {
691
696
  takerExistingBaseAssetAmount: BN | null;
692
697
  makerExistingQuoteEntryAmount: BN | null;
693
698
  makerExistingBaseAssetAmount: BN | null;
699
+ triggerPrice: BN | null;
700
+ builderIdx: number | null;
701
+ builderFee: BN | null;
694
702
  };
695
703
  export type SwapRecord = {
696
704
  ts: BN;
@@ -733,8 +741,6 @@ export type LPSwapRecord = {
733
741
  inConstituentIndex: number;
734
742
  outOraclePrice: BN;
735
743
  inOraclePrice: BN;
736
- outMint: PublicKey;
737
- inMint: PublicKey;
738
744
  lastAum: BN;
739
745
  lastAumSlot: BN;
740
746
  inMarketCurrentWeight: BN;
@@ -756,7 +762,6 @@ export type LPMintRedeemRecord = {
756
762
  constituentIndex: number;
757
763
  oraclePrice: BN;
758
764
  mint: PublicKey;
759
- lpMint: PublicKey;
760
765
  lpAmount: BN;
761
766
  lpFee: BN;
762
767
  lpPrice: BN;
@@ -796,6 +801,7 @@ export type LPBorrowLendDepositRecord = {
796
801
  export type StateAccount = {
797
802
  coldAdmin: PublicKey;
798
803
  warmAdmin: PublicKey;
804
+ pauseAdmin: PublicKey;
799
805
  hotAmmCrank: PublicKey;
800
806
  hotLpCache: PublicKey;
801
807
  hotLpSwap: PublicKey;
@@ -832,6 +838,7 @@ export type StateAccount = {
832
838
  liquidationDuration: number;
833
839
  maxInitializeUserFee: number;
834
840
  featureBitFlags: number;
841
+ lpPoolFeatureBitFlags: number;
835
842
  };
836
843
  export type PerpMarketAccount = {
837
844
  status: MarketStatus;
@@ -873,6 +880,7 @@ export type PerpMarketAccount = {
873
880
  feeAdjustment: number;
874
881
  pausedOperations: number;
875
882
  lastFillPrice: BN;
883
+ poolId: number;
876
884
  hedgeConfig: {
877
885
  poolId: number;
878
886
  status: number;
@@ -961,6 +969,7 @@ export type SpotMarketAccount = {
961
969
  maxTokenDeposits: BN;
962
970
  lastInterestTs: BN;
963
971
  lastTwapTs: BN;
972
+ expiryTs: BN;
964
973
  initialAssetWeight: number;
965
974
  maintenanceAssetWeight: number;
966
975
  initialLiabilityWeight: number;
@@ -1019,12 +1028,21 @@ export type AMM = {
1019
1028
  totalMmFee: BN;
1020
1029
  totalFeeMinusDistributions: BN;
1021
1030
  totalFeeWithdrawn: BN;
1031
+ askBaseAssetReserve: BN;
1032
+ askQuoteAssetReserve: BN;
1033
+ bidBaseAssetReserve: BN;
1034
+ bidQuoteAssetReserve: BN;
1022
1035
  lastUpdateSlot: BN;
1023
1036
  netRevenueSinceLastFunding: BN;
1024
1037
  lastCumulativeFundingRateLong: BN;
1025
1038
  lastCumulativeFundingRateShort: BN;
1039
+ lastOracleReservePriceSpreadPct: BN;
1040
+ lastSpreadUpdateSlot: BN;
1026
1041
  baseSpread: number;
1027
1042
  maxSpread: number;
1043
+ longSpread: number;
1044
+ shortSpread: number;
1045
+ referencePriceOffset: number;
1028
1046
  maxFillReserveFraction: number;
1029
1047
  maxSlippageRatio: number;
1030
1048
  curveUpdateIntensity: number;
@@ -1093,6 +1111,8 @@ export type UserStatsAccount = {
1093
1111
  };
1094
1112
  referrer: PublicKey;
1095
1113
  referrerStatus: number;
1114
+ disableUpdatePerpBidAskTwap: number;
1115
+ pausedOperations: number;
1096
1116
  authority: PublicKey;
1097
1117
  ifStakedQuoteAssetAmount: BN;
1098
1118
  delegatePermissions: number;
@@ -1375,8 +1395,8 @@ export type FeeTier = {
1375
1395
  refereeFeeDenominator: number;
1376
1396
  };
1377
1397
  export type OrderFillerRewardStructure = {
1378
- rewardNumerator: BN;
1379
- rewardDenominator: BN;
1398
+ rewardNumerator: number;
1399
+ rewardDenominator: number;
1380
1400
  timeBasedRewardLowerBound: BN;
1381
1401
  };
1382
1402
  export type OracleGuardRails = {
@@ -1409,6 +1429,22 @@ export type PrelaunchOracle = {
1409
1429
  lastUpdateSlot: BN;
1410
1430
  perpMarketIndex: number;
1411
1431
  };
1432
+ export type PrelaunchOracleParams = {
1433
+ perpMarketIndex: number;
1434
+ price: BN | null;
1435
+ maxPrice: BN | null;
1436
+ };
1437
+ export type PythLazerOracle = {
1438
+ price: BN;
1439
+ publishTime: BN;
1440
+ postedSlot: BN;
1441
+ exponent: number;
1442
+ conf: BN;
1443
+ };
1444
+ export type UpdatePerpMarketSummaryStatsParams = {
1445
+ netUnsettledFundingPnl: BN | null;
1446
+ updateAmmSummaryStats: boolean | null;
1447
+ };
1412
1448
  export type MarginCategory = 'Initial' | 'Maintenance';
1413
1449
  export type InsuranceFundStake = {
1414
1450
  costBasis: BN;
@@ -1416,6 +1452,7 @@ export type InsuranceFundStake = {
1416
1452
  authority: PublicKey;
1417
1453
  ifShares: BN;
1418
1454
  ifBase: BN;
1455
+ lastValidTs: BN;
1419
1456
  lastWithdrawRequestShares: BN;
1420
1457
  lastWithdrawRequestValue: BN;
1421
1458
  lastWithdrawRequestTs: BN;
@@ -1489,6 +1526,9 @@ export type SignedMsgUserOrdersAccount = {
1489
1526
  authorityPubkey: PublicKey;
1490
1527
  signedMsgOrderData: SignedMsgOrderId[];
1491
1528
  };
1529
+ export type SignedMsgWsDelegatesAccount = {
1530
+ delegates: PublicKey[];
1531
+ };
1492
1532
  export type RevenueShareAccount = {
1493
1533
  authority: PublicKey;
1494
1534
  totalReferrerRewards: BN;
@@ -1519,8 +1559,23 @@ export type BuilderInfo = {
1519
1559
  maxFeeTenthBps: number;
1520
1560
  padding: number[];
1521
1561
  };
1562
+ export type PerpMarketFeeSweepRecord = {
1563
+ ts: BN;
1564
+ marketIndex: number;
1565
+ ifSwept: BN;
1566
+ protocolSwept: BN;
1567
+ ammProvisionTokenized: BN;
1568
+ };
1569
+ export type ProtocolFeeWithdrawRecord = {
1570
+ ts: BN;
1571
+ marketIndex: number;
1572
+ isPerp: boolean;
1573
+ spotMarketIndex: number;
1574
+ amount: BN;
1575
+ recipientTokenAccount: PublicKey;
1576
+ };
1522
1577
  export type RevenueShareSettleRecord = {
1523
- ts: number;
1578
+ ts: BN;
1524
1579
  builder: PublicKey | null;
1525
1580
  referrer: PublicKey | null;
1526
1581
  feeSettled: BN;
@@ -1583,6 +1638,8 @@ export type LPPoolAccount = {
1583
1638
  bump: number;
1584
1639
  gammaExecution: number;
1585
1640
  xi: number;
1641
+ targetOracleDelayFeeBpsPer10Slots: number;
1642
+ targetPositionDelayFeeBpsPer10Slots: number;
1586
1643
  };
1587
1644
  export type ConstituentSpotBalance = {
1588
1645
  scaledBalance: BN;
@@ -1675,6 +1732,7 @@ export type CacheInfo = {
1675
1732
  marketIndex: number;
1676
1733
  };
1677
1734
  export type AmmCache = {
1735
+ bump: number;
1678
1736
  cache: CacheInfo[];
1679
1737
  };
1680
1738
  export type AccountLiquidatableStatus = {
@@ -1690,4 +1748,12 @@ export declare class TransferFeeAndPnlPoolDirection {
1690
1748
  pnlToFeePool: {};
1691
1749
  };
1692
1750
  }
1751
+ export type TransferFeeAndPnlPoolRecord = {
1752
+ ts: BN;
1753
+ slot: BN;
1754
+ perpMarketIndexWithFeePool: number;
1755
+ perpMarketIndexWithPnlPool: number;
1756
+ direction: TransferFeeAndPnlPoolDirection;
1757
+ amount: BN;
1758
+ };
1693
1759
  export {};
@@ -44,19 +44,35 @@ export declare class User {
44
44
  */
45
45
  fetchAccounts(): Promise<void>;
46
46
  unsubscribe(): Promise<void>;
47
+ /**
48
+ * Returns the cached user account.
49
+ *
50
+ * - **Throws** `NotSubscribedError` if the subscriber has not been subscribed
51
+ * yet — reading the account before {@link subscribe} resolves is a
52
+ * programming error, not a missing-account condition.
53
+ * - Returns `undefined` when subscribed but no account was found on chain.
54
+ * Because `subscribe()` awaits the initial fetch, an `undefined` here means
55
+ * the account does not exist (or has not yet been observed), not that data
56
+ * is "still loading".
57
+ */
47
58
  getUserAccount(): UserAccount | undefined;
48
59
  /**
49
- * Like {@link getUserAccount} but throws a named error instead of returning
50
- * `undefined` when the account has not been loaded yet. Use at call sites
51
- * that structurally require a loaded account.
60
+ * Like {@link getUserAccount} but throws instead of returning `undefined`
61
+ * when the account was not found. Use at call sites that structurally
62
+ * require the account to exist. (Still propagates `NotSubscribedError` when
63
+ * called before subscribing.)
64
+ *
65
+ * Delegates to {@link getUserAccount} (rather than the subscriber directly)
66
+ * so callers that override `getUserAccount` see the override here too.
52
67
  */
53
68
  getUserAccountOrThrow(): UserAccount;
54
69
  forceGetUserAccount(): Promise<UserAccount | undefined>;
55
70
  getUserAccountAndSlot(): DataAndSlot<UserAccount> | undefined;
56
71
  /**
57
- * Like {@link getUserAccountAndSlot} but throws a named error instead of
58
- * returning `undefined` when the account has not been loaded yet. Use at
59
- * call sites that structurally require a loaded account.
72
+ * Like {@link getUserAccountAndSlot} but throws instead of returning
73
+ * `undefined` when the account was not found. Use at call sites that
74
+ * structurally require the account to exist. (Still propagates
75
+ * `NotSubscribedError` when called before subscribing.)
60
76
  */
61
77
  getUserAccountAndSlotOrThrow(): DataAndSlot<UserAccount>;
62
78
  getPerpPositionForUserAccount(userAccount: UserAccount, marketIndex: number): PerpPosition | undefined;
@@ -92,19 +92,34 @@ class User {
92
92
  await this.accountSubscriber.unsubscribe();
93
93
  this.isSubscribed = false;
94
94
  }
95
+ /**
96
+ * Returns the cached user account.
97
+ *
98
+ * - **Throws** `NotSubscribedError` if the subscriber has not been subscribed
99
+ * yet — reading the account before {@link subscribe} resolves is a
100
+ * programming error, not a missing-account condition.
101
+ * - Returns `undefined` when subscribed but no account was found on chain.
102
+ * Because `subscribe()` awaits the initial fetch, an `undefined` here means
103
+ * the account does not exist (or has not yet been observed), not that data
104
+ * is "still loading".
105
+ */
95
106
  getUserAccount() {
96
107
  var _a;
97
108
  return (_a = this.accountSubscriber.getUserAccountAndSlot()) === null || _a === void 0 ? void 0 : _a.data;
98
109
  }
99
110
  /**
100
- * Like {@link getUserAccount} but throws a named error instead of returning
101
- * `undefined` when the account has not been loaded yet. Use at call sites
102
- * that structurally require a loaded account.
111
+ * Like {@link getUserAccount} but throws instead of returning `undefined`
112
+ * when the account was not found. Use at call sites that structurally
113
+ * require the account to exist. (Still propagates `NotSubscribedError` when
114
+ * called before subscribing.)
115
+ *
116
+ * Delegates to {@link getUserAccount} (rather than the subscriber directly)
117
+ * so callers that override `getUserAccount` see the override here too.
103
118
  */
104
119
  getUserAccountOrThrow() {
105
120
  const userAccount = this.getUserAccount();
106
121
  if (!userAccount) {
107
- throw new Error(`User account not loaded: ${this.getUserAccountPublicKey().toString()}`);
122
+ throw new Error(`User account not found: ${this.getUserAccountPublicKey().toString()}`);
108
123
  }
109
124
  return userAccount;
110
125
  }
@@ -117,12 +132,13 @@ class User {
117
132
  return this.accountSubscriber.getUserAccountAndSlot();
118
133
  }
119
134
  /**
120
- * Like {@link getUserAccountAndSlot} but throws a named error instead of
121
- * returning `undefined` when the account has not been loaded yet. Use at
122
- * call sites that structurally require a loaded account.
135
+ * Like {@link getUserAccountAndSlot} but throws instead of returning
136
+ * `undefined` when the account was not found. Use at call sites that
137
+ * structurally require the account to exist. (Still propagates
138
+ * `NotSubscribedError` when called before subscribing.)
123
139
  */
124
140
  getUserAccountAndSlotOrThrow() {
125
- return (0, utils_1.assertDataAndSlot)(this.accountSubscriber.getUserAccountAndSlot(), `User account not loaded: ${this.getUserAccountPublicKey().toString()}`);
141
+ return (0, utils_1.assertDataAndSlot)(this.accountSubscriber.getUserAccountAndSlot(), `User account not found: ${this.getUserAccountPublicKey().toString()}`);
126
142
  }
127
143
  getPerpPositionForUserAccount(userAccount, marketIndex) {
128
144
  return this.getActivePerpPositionsForUserAccount(userAccount).find((position) => position.marketIndex === marketIndex);
@@ -13,7 +13,11 @@ const PollingSubscription_1 = require("./PollingSubscription");
13
13
  const user_2 = require("../decode/user");
14
14
  const grpcSubscription_1 = require("./grpcSubscription");
15
15
  const events_1 = require("events");
16
- const MAX_USER_ACCOUNT_SIZE_BYTES = 4376;
16
+ // Velocity's User account is 4496 bytes (8-byte discriminator + 4488 struct);
17
+ // drift's was 4376. This caps the zstd-decompressed buffer in defaultSync — if it's
18
+ // smaller than the real account, the buffer is truncated and decodeUser reads past
19
+ // the end (RangeError: ERR_BUFFER_OUT_OF_BOUNDS). Must be >= the on-chain User size.
20
+ const MAX_USER_ACCOUNT_SIZE_BYTES = 4496;
17
21
  class UserMap {
18
22
  /**
19
23
  * Constructs a new UserMap instance.
@@ -199,8 +199,6 @@ export declare class VelocityClient {
199
199
  getInitializeRevenueShareEscrowIx(authority: PublicKey, numOrders: number, overrides?: {
200
200
  payer?: PublicKey;
201
201
  }): Promise<TransactionInstruction>;
202
- migrateReferrer(authority: PublicKey, txParams?: TxParams): Promise<TransactionSignature>;
203
- getMigrateReferrerIx(authority: PublicKey): Promise<TransactionInstruction>;
204
202
  resizeRevenueShareEscrowOrders(authority: PublicKey, numOrders: number, txParams?: TxParams): Promise<TransactionSignature>;
205
203
  getResizeRevenueShareEscrowOrdersIx(authority: PublicKey, numOrders: number): Promise<TransactionInstruction>;
206
204
  /**
@@ -728,24 +728,6 @@ class VelocityClient {
728
728
  },
729
729
  });
730
730
  }
731
- async migrateReferrer(authority, txParams) {
732
- const ix = await this.getMigrateReferrerIx(authority);
733
- const tx = await this.buildTransaction([ix], txParams);
734
- const { txSig } = await this.sendTransaction(tx, [], this.opts);
735
- return txSig;
736
- }
737
- async getMigrateReferrerIx(authority) {
738
- const escrow = (0, pda_1.getRevenueShareEscrowAccountPublicKey)(this.program.programId, authority);
739
- return this.program.instruction.migrateReferrer({
740
- accounts: {
741
- escrow,
742
- authority,
743
- userStats: (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, authority),
744
- state: await this.getStatePublicKey(),
745
- payer: this.wallet.publicKey,
746
- },
747
- });
748
- }
749
731
  async resizeRevenueShareEscrowOrders(authority, numOrders, txParams) {
750
732
  const ix = await this.getResizeRevenueShareEscrowOrdersIx(authority, numOrders);
751
733
  const tx = await this.buildTransaction([ix], txParams);
@@ -34,6 +34,5 @@ export declare class grpcMultiAccountSubscriber<T, U = undefined> {
34
34
  removeAccounts(accounts: PublicKey[]): Promise<void>;
35
35
  unsubscribe(): Promise<void>;
36
36
  private setTimeout;
37
- private capitalize;
38
37
  }
39
38
  //# sourceMappingURL=grpcMultiAccountSubscriber.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAI5C,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAiB,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyB7E,qBAAa,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAC,CAAqB;IACrC,OAAO,KAAK,MAAM,GAOjB;IACD,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAIhB;IACP,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAQf;IAEJ,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO;WAsBa,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EAC1C,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,EACxB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,EACvE,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB5C,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAIjE,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoEtB,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,GAAG,SAAS,KACvB,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IAsIV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,UAAU;CAIlB"}
1
+ {"version":3,"file":"grpcMultiAccountSubscriber.d.ts","sourceRoot":"","sources":["../../../src/accounts/grpcMultiAccountSubscriber.ts"],"names":[],"mappings":";;AAAA,OAAO,EAAc,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAI5C,OAAO,EACN,MAAM,EAMN,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAiB,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAyB7E,qBAAa,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS;IACvD,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAC,CAAqB;IACrC,OAAO,KAAK,MAAM,GAOjB;IACD,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,cAAc,CAAC,CAIhB;IACP,OAAO,CAAC,SAAS,CAAC,CAAY;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAsB;IAErC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,UAAS;IAC/B,OAAO,CAAC,SAAS,CAAC,CAAgC;IAClD,OAAO,CAAC,aAAa,CAAS;IAE9B,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,WAAW,CAQf;IAEJ,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,eAAe,CAAmC;IAC1D,OAAO,CAAC,SAAS,CAAoC;IAErD,OAAO;WAsBa,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,EAC1C,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,EACxB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,KAAK,CAAC,EACvE,SAAS,CAAC,EAAE,SAAS,EACrB,UAAU,CAAC,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GACzC,OAAO,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAwB5C,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;IAInE,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,SAAS;IAIjE,iBAAiB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoEtB,SAAS,CACd,QAAQ,EAAE,SAAS,EAAE,EACrB,QAAQ,EAAE,CACT,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,CAAC,GAAG,SAAS,KACvB,IAAI,GACP,OAAO,CAAC,IAAI,CAAC;IAmIV,WAAW,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCjD,cAAc,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmCpD,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IA4ClC,OAAO,CAAC,UAAU;CAclB"}