zo-sdk 0.0.45 → 0.0.47

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/src/data.ts CHANGED
@@ -199,6 +199,16 @@ export interface IStakePool {
199
199
  lockDuration: number
200
200
  }
201
201
 
202
+ export interface IMarketValidationResult {
203
+ handledVaults: Record<string, {
204
+ weight: number;
205
+ value: number;
206
+ }>;
207
+ totalWeight: number;
208
+ totalVaultsValue: number;
209
+ marketValue: number;
210
+ }
211
+
202
212
  export class DataAPI extends OracleAPI {
203
213
  provider: SuiClient
204
214
  apiEndpoint: string
@@ -305,6 +315,30 @@ export class DataAPI extends OracleAPI {
305
315
  }
306
316
  }
307
317
 
318
+ /**
319
+ * Validates the market valuation by calling the validate_market_valuation Move function
320
+ * @param tx Transaction object
321
+ * @returns An object containing handled vaults, total weight, total vaults value, and market value
322
+ */
323
+ validateMarketValuation = (tx: Transaction) => {
324
+ // First, create the valuations using existing methods
325
+ const vaultsValuation = this.valuateVaults(tx);
326
+ const symbolsValuation = this.valuateSymbols(tx);
327
+
328
+ // Call the validate_market_valuation Move function
329
+ const result = tx.moveCall({
330
+ target: `${this.consts.zoCore.upgradedPackage}::market::validate_market_valuation`,
331
+ typeArguments: [`${this.consts.zoCore.package}::zlp::ZLP`],
332
+ arguments: [
333
+ tx.object(this.consts.zoCore.market),
334
+ vaultsValuation,
335
+ symbolsValuation,
336
+ ],
337
+ });
338
+
339
+ return result;
340
+ }
341
+
308
342
  #parseMarketInfo(raw: any): IMarketInfo {
309
343
  const content = raw.data.content.fields
310
344
 
@@ -681,106 +715,147 @@ export class DataAPI extends OracleAPI {
681
715
  }
682
716
 
683
717
  public async getPositionCapInfoList(owner: string): Promise<IPositionCapInfo[]> {
684
- const positionCaps = await this.provider.getOwnedObjects({
685
- owner,
686
- filter: {
687
- MoveModule: {
688
- package: this.consts.zoCore.package,
689
- module: 'market',
718
+ const positionCapInfoList: IPositionCapInfo[] = [];
719
+ let cursor: string | undefined | null = undefined;
720
+ let hasNextPage = true;
721
+
722
+ while (hasNextPage) {
723
+ const positionCaps = await this.provider.getOwnedObjects({
724
+ owner,
725
+ filter: {
726
+ MoveModule: {
727
+ package: this.consts.zoCore.package,
728
+ module: 'market',
729
+ },
690
730
  },
691
- },
692
- options: {
693
- showType: true,
694
- },
695
- })
696
- const positionCapInfoList = []
697
- for (const positionCap of positionCaps.data) {
698
- if (positionCap.data?.type?.includes('PositionCap')) {
699
- positionCapInfoList.push({
700
- positionCapId: positionCap.data.objectId,
701
- symbol0: positionCap.data.type.split('<')[1].split(',')[0].trim(),
702
- symbol1: positionCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
703
- long: positionCap.data.type.includes('LONG'),
704
- })
731
+ options: {
732
+ showType: true,
733
+ },
734
+ cursor,
735
+ })
736
+
737
+ for (const positionCap of positionCaps.data) {
738
+ if (positionCap.data?.type?.includes('PositionCap')) {
739
+ positionCapInfoList.push({
740
+ positionCapId: positionCap.data.objectId,
741
+ symbol0: positionCap.data.type.split('<')[1].split(',')[0].trim(),
742
+ symbol1: positionCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
743
+ long: positionCap.data.type.includes('LONG'),
744
+ })
745
+ }
705
746
  }
747
+
748
+ // If we don't want to fetch all pages or there are no more pages, break the loop
749
+ hasNextPage = positionCaps.hasNextPage
750
+ cursor = positionCaps.nextCursor
706
751
  }
752
+
707
753
  return positionCapInfoList
708
754
  }
709
755
 
710
- public async getPositionInfoList(positionCapInfoList: IPositionCapInfo[], owner: string) {
756
+ public async getPositionInfoList(positionCapInfoList: IPositionCapInfo[], owner: string, batchSize: number = 10) {
711
757
  const positionInfoList: IPositionInfo[] = []
712
- await Promise.all(positionCapInfoList.map(async (positionCapInfo) => {
713
- try {
714
- const positionRaw = await this.provider.getDynamicFieldObject({
715
- parentId: this.consts.zoCore.positionsParent,
716
- name: {
717
- type: `${this.consts.zoCore.package}::market::PositionName<${positionCapInfo.symbol0}, ${positionCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${positionCapInfo.long ? 'LONG' : 'SHORT'}>`,
718
- value: {
719
- owner,
720
- id: positionCapInfo.positionCapId,
758
+
759
+ // Process in batches of 10
760
+ for (let i = 0; i < positionCapInfoList.length; i += batchSize) {
761
+ const batch = positionCapInfoList.slice(i, i + batchSize)
762
+
763
+ await Promise.all(batch.map(async (positionCapInfo) => {
764
+ try {
765
+ const positionRaw = await this.provider.getDynamicFieldObject({
766
+ parentId: this.consts.zoCore.positionsParent,
767
+ name: {
768
+ type: `${this.consts.zoCore.package}::market::PositionName<${positionCapInfo.symbol0}, ${positionCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${positionCapInfo.long ? 'LONG' : 'SHORT'}>`,
769
+ value: {
770
+ owner,
771
+ id: positionCapInfo.positionCapId,
772
+ },
721
773
  },
722
- },
723
- })
724
- positionInfoList.push(await this.#parsePositionInfo(positionRaw, positionCapInfo.positionCapId))
725
- }
726
- catch (error) {
727
- // Position might have been deleted after force settlement
728
- console.warn(`Failed to parse position info for position cap ID ${positionCapInfo.positionCapId}: ${error}`)
729
- // Continue with next position without adding this one to the list
730
- }
731
- }))
774
+ })
775
+ positionInfoList.push(await this.#parsePositionInfo(positionRaw, positionCapInfo.positionCapId))
776
+ } catch (error) {
777
+ // Position might have been deleted after force settlement
778
+ console.warn(`Failed to parse position info for position cap ID ${positionCapInfo.positionCapId}: ${error}`)
779
+ // Continue with next position without adding this one to the list
780
+ }
781
+ }))
782
+ }
732
783
 
733
784
  return positionInfoList.sort((a, b) => a.openTimestamp > b.openTimestamp ? 1 : -1)
734
785
  }
735
786
 
736
- public async getOrderCapInfoList(owner: string) {
737
- const orderCaps = await this.provider.getOwnedObjects({
738
- owner,
739
- filter: {
740
- MoveModule: {
741
- package: this.consts.zoCore.package,
742
- module: 'market',
787
+ public async getOrderCapInfoList(owner: string): Promise<IOrderCapInfo[]> {
788
+ const orderCapInfoList: IOrderCapInfo[] = [];
789
+ let cursor: string | undefined | null = undefined;
790
+ let hasNextPage = true;
791
+
792
+ while (hasNextPage) {
793
+ const orderCaps = await this.provider.getOwnedObjects({
794
+ owner,
795
+ filter: {
796
+ MoveModule: {
797
+ package: this.consts.zoCore.package,
798
+ module: 'market',
799
+ },
743
800
  },
744
- },
745
- options: {
746
- showType: true,
747
- showContent: true,
748
- },
749
- })
750
- const orderCapInfoList = []
751
- for (const orderCap of orderCaps.data) {
752
- if (orderCap.data?.type?.includes('OrderCap')) {
753
- orderCapInfoList.push({
754
- orderCapId: orderCap.data.objectId,
755
- symbol0: orderCap.data.type.split('<')[1].split(',')[0].trim(),
756
- symbol1: orderCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
757
- long: orderCap.data.type.includes('LONG'),
758
- positionId: (orderCap.data.content as any)?.fields?.position_id,
759
- })
801
+ options: {
802
+ showType: true,
803
+ showContent: true,
804
+ },
805
+ cursor,
806
+ })
807
+
808
+ for (const orderCap of orderCaps.data) {
809
+ if (orderCap.data?.type?.includes('OrderCap')) {
810
+ orderCapInfoList.push({
811
+ orderCapId: orderCap.data.objectId,
812
+ symbol0: orderCap.data.type.split('<')[1].split(',')[0].trim(),
813
+ symbol1: orderCap.data.type.split('<')[1].split(',')[1].split(',')[0].trim(),
814
+ long: orderCap.data.type.includes('LONG'),
815
+ positionId: (orderCap.data.content as any)?.fields?.position_id,
816
+ })
817
+ }
760
818
  }
819
+
820
+ hasNextPage = orderCaps.hasNextPage;
821
+ cursor = orderCaps.nextCursor;
761
822
  }
823
+
762
824
  return orderCapInfoList
763
825
  }
764
826
 
765
- public async getOrderInfoList(orderCapInfoList: IOrderCapInfo[], owner: string) {
827
+ public async getOrderInfoList(orderCapInfoList: IOrderCapInfo[], owner: string, batchSize: number = 10) {
766
828
  const orderInfoList: IOrderInfo[] = []
767
- await Promise.all(orderCapInfoList.map(async (orderCapInfo) => {
768
- const orderRaw = await this.provider.getDynamicFieldObject({
769
- parentId: this.consts.zoCore.ordersParent,
770
- name: {
771
- // We have enforced collateral coin type to match with fee coin type so we can use symbol0 in the first slot and the last slot of the OrderName
772
- type: `${this.consts.zoCore.package}::market::OrderName<${orderCapInfo.symbol0}, ${orderCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${orderCapInfo.long ? 'LONG' : 'SHORT'}, ${orderCapInfo.symbol0}>`,
773
- value: {
774
- owner,
775
- id: orderCapInfo.orderCapId,
776
- position_id: {
777
- vec: orderCapInfo.positionId ? [orderCapInfo.positionId] : [],
829
+
830
+ // Process in batches of 10
831
+ for (let i = 0; i < orderCapInfoList.length; i += batchSize) {
832
+ const batch = orderCapInfoList.slice(i, i + batchSize)
833
+
834
+ await Promise.all(batch.map(async (orderCapInfo) => {
835
+ try {
836
+ const orderRaw = await this.provider.getDynamicFieldObject({
837
+ parentId: this.consts.zoCore.ordersParent,
838
+ name: {
839
+ // We have enforced collateral coin type to match with fee coin type so we can use symbol0 in the first slot and the last slot of the OrderName
840
+ type: `${this.consts.zoCore.package}::market::OrderName<${orderCapInfo.symbol0}, ${orderCapInfo.symbol1}, ${this.consts.zoCore.package}::market::${orderCapInfo.long ? 'LONG' : 'SHORT'}, ${orderCapInfo.symbol0}>`,
841
+ value: {
842
+ owner,
843
+ id: orderCapInfo.orderCapId,
844
+ position_id: {
845
+ vec: orderCapInfo.positionId ? [orderCapInfo.positionId] : [],
846
+ },
847
+ },
778
848
  },
779
- },
780
- },
781
- })
782
- orderInfoList.push(this.#parseOrderInfo(orderRaw, orderCapInfo.orderCapId))
783
- }))
849
+ })
850
+ orderInfoList.push(this.#parseOrderInfo(orderRaw, orderCapInfo.orderCapId))
851
+ } catch (error) {
852
+ // Order might have been deleted
853
+ console.warn(`Failed to parse order info for order cap ID ${orderCapInfo.orderCapId}: ${error}`)
854
+ // Continue with next order without adding this one to the list
855
+ }
856
+ }))
857
+ }
858
+
784
859
  return orderInfoList.sort((a, b) => a.createdAt > b.createdAt ? 1 : -1)
785
860
  }
786
861