@zoguxprotocol/client-js 0.2.5 → 0.2.7

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 (102) hide show
  1. package/__native__/__ios__/v4-native-client.js +785 -23
  2. package/__native__/__ios__/v4-native-client.js.map +1 -1
  3. package/__tests__/clients/composite-client.test.ts +7 -1
  4. package/__tests__/helpers/constants.ts +14 -3
  5. package/__tests__/lib/composer-spot-perp.test.ts +82 -0
  6. package/__tests__/lib/validation.test.ts +83 -3
  7. package/build/cjs/__tests__/clients/composite-client.test.js +6 -1
  8. package/build/cjs/__tests__/helpers/constants.js +14 -5
  9. package/build/cjs/__tests__/lib/composer-spot-perp.test.js +76 -0
  10. package/build/cjs/__tests__/lib/validation.test.js +69 -4
  11. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/cosmos/bundle.js +126 -126
  12. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/bundle.js +168 -162
  13. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/events/events.js +37 -5
  14. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/protocol/v1/subaccount.js +46 -2
  15. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/rpc.tx.js +2 -1
  16. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/transfer.js +326 -2
  17. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.js +132 -2
  18. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.rpc.msg.js +31 -1
  19. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/spot_position.js +82 -0
  20. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/subaccount.js +20 -3
  21. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.js +125 -0
  22. package/build/cjs/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.rpc.msg.js +51 -0
  23. package/build/cjs/src/clients/constants.js +8 -3
  24. package/build/cjs/src/clients/lib/registry.js +11 -6
  25. package/build/cjs/src/clients/modules/account.js +13 -1
  26. package/build/cjs/src/clients/modules/composer.js +47 -1
  27. package/build/cjs/src/clients/modules/post.js +36 -1
  28. package/build/cjs/src/clients/types.js +1 -1
  29. package/build/cjs/src/lib/validation.js +53 -1
  30. package/build/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  31. package/build/esm/__tests__/clients/composite-client.test.js +6 -1
  32. package/build/esm/__tests__/helpers/constants.d.ts +2 -1
  33. package/build/esm/__tests__/helpers/constants.d.ts.map +1 -1
  34. package/build/esm/__tests__/helpers/constants.js +13 -4
  35. package/build/esm/__tests__/lib/composer-spot-perp.test.d.ts +2 -0
  36. package/build/esm/__tests__/lib/composer-spot-perp.test.d.ts.map +1 -0
  37. package/build/esm/__tests__/lib/composer-spot-perp.test.js +71 -0
  38. package/build/esm/__tests__/lib/validation.test.js +71 -6
  39. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/cosmos/bundle.d.ts +158 -158
  40. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/cosmos/bundle.js +126 -126
  41. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/bundle.d.ts +551 -476
  42. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/bundle.d.ts.map +1 -1
  43. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/bundle.js +168 -162
  44. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/events/events.d.ts +14 -1
  45. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/events/events.d.ts.map +1 -1
  46. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/events/events.js +38 -6
  47. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/protocol/v1/subaccount.d.ts +27 -0
  48. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/protocol/v1/subaccount.d.ts.map +1 -1
  49. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/indexer/protocol/v1/subaccount.js +45 -1
  50. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/rpc.tx.d.ts +1 -0
  51. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/rpc.tx.d.ts.map +1 -1
  52. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/rpc.tx.js +2 -1
  53. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/transfer.d.ts +156 -0
  54. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/transfer.d.ts.map +1 -1
  55. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/transfer.js +325 -1
  56. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.d.ts +79 -0
  57. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.d.ts.map +1 -1
  58. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.js +131 -1
  59. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.rpc.msg.d.ts +29 -2
  60. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.rpc.msg.d.ts.map +1 -1
  61. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/sending/tx.rpc.msg.js +33 -3
  62. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/spot_position.d.ts +30 -0
  63. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/spot_position.d.ts.map +1 -0
  64. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/spot_position.js +46 -0
  65. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/subaccount.d.ts +16 -1
  66. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/subaccount.d.ts.map +1 -1
  67. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/subaccount.js +20 -3
  68. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.d.ts +41 -0
  69. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.d.ts.map +1 -0
  70. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.js +89 -0
  71. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.rpc.msg.d.ts +16 -0
  72. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.rpc.msg.d.ts.map +1 -0
  73. package/build/esm/node_modules/@zoguxprotocol/proto/src/codegen/zogux/subaccounts/tx.rpc.msg.js +14 -0
  74. package/build/esm/src/clients/constants.d.ts +5 -0
  75. package/build/esm/src/clients/constants.d.ts.map +1 -1
  76. package/build/esm/src/clients/constants.js +6 -1
  77. package/build/esm/src/clients/lib/registry.d.ts.map +1 -1
  78. package/build/esm/src/clients/lib/registry.js +9 -4
  79. package/build/esm/src/clients/modules/account.d.ts +5 -0
  80. package/build/esm/src/clients/modules/account.d.ts.map +1 -1
  81. package/build/esm/src/clients/modules/account.js +13 -1
  82. package/build/esm/src/clients/modules/composer.d.ts +5 -0
  83. package/build/esm/src/clients/modules/composer.d.ts.map +1 -1
  84. package/build/esm/src/clients/modules/composer.js +48 -2
  85. package/build/esm/src/clients/modules/post.d.ts +10 -0
  86. package/build/esm/src/clients/modules/post.d.ts.map +1 -1
  87. package/build/esm/src/clients/modules/post.js +36 -1
  88. package/build/esm/src/clients/types.d.ts +14 -0
  89. package/build/esm/src/clients/types.d.ts.map +1 -1
  90. package/build/esm/src/clients/types.js +1 -1
  91. package/build/esm/src/lib/validation.d.ts +11 -1
  92. package/build/esm/src/lib/validation.d.ts.map +1 -1
  93. package/build/esm/src/lib/validation.js +51 -1
  94. package/build/esm/tsconfig.esm.tsbuildinfo +1 -1
  95. package/package.json +2 -2
  96. package/src/clients/constants.ts +5 -0
  97. package/src/clients/lib/registry.ts +16 -1
  98. package/src/clients/modules/account.ts +17 -0
  99. package/src/clients/modules/composer.ts +88 -0
  100. package/src/clients/modules/post.ts +141 -0
  101. package/src/clients/types.ts +9 -0
  102. package/src/lib/validation.ts +62 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zoguxprotocol/client-js",
3
- "version": "0.2.5",
3
+ "version": "0.2.7",
4
4
  "description": "General client library for the new Zogux system (v4 decentralized)",
5
5
  "main": "build/cjs/src/index.js",
6
6
  "module": "build/esm/src/index.js",
@@ -55,7 +55,7 @@
55
55
  "@osmonauts/lcd": "^0.6.0",
56
56
  "@scure/bip32": "^1.1.5",
57
57
  "@scure/bip39": "^1.1.1",
58
- "@zoguxprotocol/proto": "0.1.5",
58
+ "@zoguxprotocol/proto": "0.1.7",
59
59
  "axios": "1.1.3",
60
60
  "bech32": "^1.1.4",
61
61
  "bignumber.js": "^9.1.1",
@@ -101,6 +101,11 @@ export const TYPE_URL_MSG_CREATE_TRANSFER = '/zogux.sending.MsgCreateTransfer';
101
101
  export const TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT =
102
102
  '/zogux.sending.MsgWithdrawFromSubaccount';
103
103
  export const TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT = '/zogux.sending.MsgDepositToSubaccount';
104
+ export const TYPE_URL_MSG_TRANSFER_SPOT_TO_PERP = '/zogux.sending.MsgTransferSpotToPerp';
105
+ export const TYPE_URL_MSG_TRANSFER_PERP_TO_SPOT = '/zogux.sending.MsgTransferPerpToSpot';
106
+ export const TYPE_URL_MSG_CREATE_TRANSFER_SPOT = '/zogux.sending.MsgCreateTransferSpot';
107
+ export const TYPE_URL_MSG_DEPOSIT_TO_SPOT = '/zogux.sending.MsgDepositToSpot';
108
+ export const TYPE_URL_MSG_WITHDRAW_FROM_SPOT = '/zogux.sending.MsgWithdrawFromSpot';
104
109
 
105
110
  // x/affiliates
106
111
  export const TYPE_URL_MSG_REGISTER_AFFILIATE = '/zogux.affiliates.MsgRegisterAffiliate';
@@ -16,8 +16,12 @@ import { MsgCreateOracleMarket } from '@zoguxprotocol/proto/src/codegen/zogux/pr
16
16
  import {
17
17
  MsgWithdrawFromSubaccount,
18
18
  MsgDepositToSubaccount,
19
+ MsgTransferSpotToPerp,
20
+ MsgTransferPerpToSpot,
21
+ MsgCreateTransferSpot,
22
+ MsgDepositToSpot,
23
+ MsgWithdrawFromSpot,
19
24
  } from '@zoguxprotocol/proto/src/codegen/zogux/sending/transfer';
20
- import { MsgCreateTransfer } from '@zoguxprotocol/proto/src/codegen/zogux/sending/tx';
21
25
  import {
22
26
  MsgDepositToMegavault,
23
27
  MsgWithdrawFromMegavault,
@@ -34,6 +38,11 @@ import {
34
38
  TYPE_URL_MSG_CREATE_TRANSFER,
35
39
  TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT,
36
40
  TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT,
41
+ TYPE_URL_MSG_TRANSFER_SPOT_TO_PERP,
42
+ TYPE_URL_MSG_TRANSFER_PERP_TO_SPOT,
43
+ TYPE_URL_MSG_CREATE_TRANSFER_SPOT,
44
+ TYPE_URL_MSG_DEPOSIT_TO_SPOT,
45
+ TYPE_URL_MSG_WITHDRAW_FROM_SPOT,
37
46
  TYPE_URL_BATCH_CANCEL,
38
47
  TYPE_URL_MSG_DEPOSIT_TO_MEGAVAULT,
39
48
  TYPE_URL_MSG_WITHDRAW_FROM_MEGAVAULT,
@@ -42,6 +51,7 @@ import {
42
51
  TYPE_URL_MSG_ADD_AUTHENTICATOR,
43
52
  TYPE_URL_MSG_REMOVE_AUTHENTICATOR,
44
53
  } from '../constants';
54
+ import { MsgCreateTransfer } from '../types';
45
55
 
46
56
  export const registry: ReadonlyArray<[string, GeneratedType]> = [];
47
57
  export function generateRegistry(): Registry {
@@ -73,6 +83,11 @@ export function generateRegistry(): Registry {
73
83
  [TYPE_URL_MSG_CREATE_TRANSFER, MsgCreateTransfer as GeneratedType],
74
84
  [TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT, MsgWithdrawFromSubaccount as GeneratedType],
75
85
  [TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT, MsgDepositToSubaccount as GeneratedType],
86
+ [TYPE_URL_MSG_TRANSFER_SPOT_TO_PERP, MsgTransferSpotToPerp as GeneratedType],
87
+ [TYPE_URL_MSG_TRANSFER_PERP_TO_SPOT, MsgTransferPerpToSpot as GeneratedType],
88
+ [TYPE_URL_MSG_CREATE_TRANSFER_SPOT, MsgCreateTransferSpot as GeneratedType],
89
+ [TYPE_URL_MSG_DEPOSIT_TO_SPOT, MsgDepositToSpot as GeneratedType],
90
+ [TYPE_URL_MSG_WITHDRAW_FROM_SPOT, MsgWithdrawFromSpot as GeneratedType],
76
91
 
77
92
  // affiliates
78
93
  [TYPE_URL_MSG_REGISTER_AFFILIATE, MsgRegisterAffiliate as GeneratedType],
@@ -70,6 +70,23 @@ export default class AccountClient extends RestClient {
70
70
  });
71
71
  }
72
72
 
73
+ /**
74
+ * Spot asset positions (spot balance per subaccount/asset).
75
+ * Use for display and validation when building Spot→Perp or Perp→Spot transfers.
76
+ */
77
+ async getSpotAssetPositions(
78
+ address: string,
79
+ subaccountNumber: number,
80
+ limit?: number | null,
81
+ ): Promise<Data> {
82
+ const uri = '/v4/spotAssetPositions';
83
+ return this.get(uri, {
84
+ address,
85
+ subaccountNumber,
86
+ limit,
87
+ });
88
+ }
89
+
73
90
  // ------ Transfers ------ //
74
91
 
75
92
  async getTransfersBetween(
@@ -45,6 +45,11 @@ import {
45
45
  TYPE_URL_MSG_CREATE_TRANSFER,
46
46
  TYPE_URL_MSG_WITHDRAW_FROM_SUBACCOUNT,
47
47
  TYPE_URL_MSG_DEPOSIT_TO_SUBACCOUNT,
48
+ TYPE_URL_MSG_TRANSFER_SPOT_TO_PERP,
49
+ TYPE_URL_MSG_TRANSFER_PERP_TO_SPOT,
50
+ TYPE_URL_MSG_CREATE_TRANSFER_SPOT,
51
+ TYPE_URL_MSG_DEPOSIT_TO_SPOT,
52
+ TYPE_URL_MSG_WITHDRAW_FROM_SPOT,
48
53
  TYPE_URL_MSG_DELEGATE,
49
54
  TYPE_URL_MSG_UNDELEGATE,
50
55
  TYPE_URL_MSG_WITHDRAW_DELEGATOR_REWARD,
@@ -338,6 +343,89 @@ export class Composer {
338
343
  };
339
344
  }
340
345
 
346
+ public composeMsgTransferSpotToPerp(
347
+ senderAddress: string,
348
+ senderSubaccountNumber: number,
349
+ recipientOwner: string,
350
+ recipientSubaccountNumber: number,
351
+ assetId: number,
352
+ quantums: Long,
353
+ ): EncodeObject {
354
+ const senderSubaccountId: SubaccountId = { owner: senderAddress, number: senderSubaccountNumber };
355
+ const recipientSubaccountId: SubaccountId = { owner: recipientOwner, number: recipientSubaccountNumber };
356
+ const quantumsBigInt = typeof quantums === 'bigint' ? quantums : BigInt(quantums.toString());
357
+ return {
358
+ typeUrl: TYPE_URL_MSG_TRANSFER_SPOT_TO_PERP,
359
+ value: {
360
+ sender: senderAddress,
361
+ senderSubaccountId,
362
+ recipientSubaccountId,
363
+ assetId,
364
+ quantums: quantumsBigInt,
365
+ },
366
+ };
367
+ }
368
+
369
+ public composeMsgTransferPerpToSpot(
370
+ senderAddress: string,
371
+ senderSubaccountNumber: number,
372
+ recipientOwner: string,
373
+ recipientSubaccountNumber: number,
374
+ assetId: number,
375
+ quantums: Long,
376
+ ): EncodeObject {
377
+ const senderSubaccountId: SubaccountId = { owner: senderAddress, number: senderSubaccountNumber };
378
+ const recipientSubaccountId: SubaccountId = { owner: recipientOwner, number: recipientSubaccountNumber };
379
+ const quantumsBigInt = typeof quantums === 'bigint' ? quantums : BigInt(quantums.toString());
380
+ return {
381
+ typeUrl: TYPE_URL_MSG_TRANSFER_PERP_TO_SPOT,
382
+ value: {
383
+ sender: senderAddress,
384
+ senderSubaccountId,
385
+ recipientSubaccountId,
386
+ assetId,
387
+ quantums: quantumsBigInt,
388
+ },
389
+ };
390
+ }
391
+
392
+ public composeMsgCreateTransferSpot(
393
+ senderAddress: string,
394
+ senderSubaccountNumber: number,
395
+ recipientOwner: string,
396
+ recipientSubaccountNumber: number,
397
+ assetId: number,
398
+ quantums: Long,
399
+ ): EncodeObject {
400
+ const senderSubaccountId: SubaccountId = { owner: senderAddress, number: senderSubaccountNumber };
401
+ const recipientSubaccountId: SubaccountId = { owner: recipientOwner, number: recipientSubaccountNumber };
402
+ const quantumsBigInt = typeof quantums === 'bigint' ? quantums : BigInt(quantums.toString());
403
+ return { typeUrl: TYPE_URL_MSG_CREATE_TRANSFER_SPOT, value: { sender: senderAddress, senderSubaccountId, recipientSubaccountId, assetId, quantums: quantumsBigInt } };
404
+ }
405
+
406
+ public composeMsgDepositToSpot(
407
+ address: string,
408
+ subaccountNumber: number,
409
+ assetId: number,
410
+ quantums: Long,
411
+ ): EncodeObject {
412
+ const recipient: SubaccountId = { owner: address, number: subaccountNumber };
413
+ const quantumsBigInt = typeof quantums === 'bigint' ? quantums : BigInt(quantums.toString());
414
+ return { typeUrl: TYPE_URL_MSG_DEPOSIT_TO_SPOT, value: { sender: address, recipient, assetId, quantums: quantumsBigInt } };
415
+ }
416
+
417
+ public composeMsgWithdrawFromSpot(
418
+ address: string,
419
+ subaccountNumber: number,
420
+ assetId: number,
421
+ quantums: Long,
422
+ recipient: string = address,
423
+ ): EncodeObject {
424
+ const sender: SubaccountId = { owner: address, number: subaccountNumber };
425
+ const quantumsBigInt = typeof quantums === 'bigint' ? quantums : BigInt(quantums.toString());
426
+ return { typeUrl: TYPE_URL_MSG_WITHDRAW_FROM_SPOT, value: { sender, recipient, assetId, quantums: quantumsBigInt } };
427
+ }
428
+
341
429
  // ------------ x/bank ------------
342
430
  public composeMsgSendToken(
343
431
  address: string,
@@ -757,6 +757,147 @@ export class Post {
757
757
  });
758
758
  }
759
759
 
760
+ async transferSpotToPerp(
761
+ subaccount: SubaccountInfo,
762
+ recipientOwner: string,
763
+ recipientSubaccountNumber: number,
764
+ assetId: number,
765
+ quantums: Long,
766
+ broadcastMode?: BroadcastMode,
767
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
768
+ const msg = await this.transferSpotToPerpMsg(
769
+ subaccount.address,
770
+ subaccount.subaccountNumber,
771
+ recipientOwner,
772
+ recipientSubaccountNumber,
773
+ assetId,
774
+ quantums,
775
+ );
776
+ return this.send(subaccount, () => Promise.resolve([msg]), false, undefined, undefined, broadcastMode);
777
+ }
778
+
779
+ async transferSpotToPerpMsg(
780
+ senderAddress: string,
781
+ senderSubaccountNumber: number,
782
+ recipientOwner: string,
783
+ recipientSubaccountNumber: number,
784
+ assetId: number,
785
+ quantums: Long,
786
+ ): Promise<EncodeObject> {
787
+ return Promise.resolve(
788
+ this.composer.composeMsgTransferSpotToPerp(
789
+ senderAddress,
790
+ senderSubaccountNumber,
791
+ recipientOwner,
792
+ recipientSubaccountNumber,
793
+ assetId,
794
+ quantums,
795
+ ),
796
+ );
797
+ }
798
+
799
+ async transferPerpToSpot(
800
+ subaccount: SubaccountInfo,
801
+ recipientOwner: string,
802
+ recipientSubaccountNumber: number,
803
+ assetId: number,
804
+ quantums: Long,
805
+ broadcastMode?: BroadcastMode,
806
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
807
+ const msg = await this.transferPerpToSpotMsg(
808
+ subaccount.address,
809
+ subaccount.subaccountNumber,
810
+ recipientOwner,
811
+ recipientSubaccountNumber,
812
+ assetId,
813
+ quantums,
814
+ );
815
+ return this.send(subaccount, () => Promise.resolve([msg]), false, undefined, undefined, broadcastMode);
816
+ }
817
+
818
+ async transferPerpToSpotMsg(
819
+ senderAddress: string,
820
+ senderSubaccountNumber: number,
821
+ recipientOwner: string,
822
+ recipientSubaccountNumber: number,
823
+ assetId: number,
824
+ quantums: Long,
825
+ ): Promise<EncodeObject> {
826
+ return Promise.resolve(
827
+ this.composer.composeMsgTransferPerpToSpot(
828
+ senderAddress,
829
+ senderSubaccountNumber,
830
+ recipientOwner,
831
+ recipientSubaccountNumber,
832
+ assetId,
833
+ quantums,
834
+ ),
835
+ );
836
+ }
837
+
838
+ async createTransferSpot(
839
+ subaccount: SubaccountInfo,
840
+ recipientOwner: string,
841
+ recipientSubaccountNumber: number,
842
+ assetId: number,
843
+ quantums: Long,
844
+ broadcastMode?: BroadcastMode,
845
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
846
+ const msg = await this.createTransferSpotMsg(subaccount.address, subaccount.subaccountNumber, recipientOwner, recipientSubaccountNumber, assetId, quantums);
847
+ return this.send(subaccount, () => Promise.resolve([msg]), false, undefined, undefined, broadcastMode);
848
+ }
849
+
850
+ async createTransferSpotMsg(
851
+ senderAddress: string,
852
+ senderSubaccountNumber: number,
853
+ recipientOwner: string,
854
+ recipientSubaccountNumber: number,
855
+ assetId: number,
856
+ quantums: Long,
857
+ ): Promise<EncodeObject> {
858
+ return Promise.resolve(this.composer.composeMsgCreateTransferSpot(senderAddress, senderSubaccountNumber, recipientOwner, recipientSubaccountNumber, assetId, quantums));
859
+ }
860
+
861
+ async depositToSpot(
862
+ subaccount: SubaccountInfo,
863
+ assetId: number,
864
+ quantums: Long,
865
+ broadcastMode?: BroadcastMode,
866
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
867
+ const msg = await this.depositToSpotMsg(subaccount.address, subaccount.subaccountNumber, assetId, quantums);
868
+ return this.send(subaccount, () => Promise.resolve([msg]), false, undefined, undefined, broadcastMode);
869
+ }
870
+
871
+ async depositToSpotMsg(
872
+ address: string,
873
+ subaccountNumber: number,
874
+ assetId: number,
875
+ quantums: Long,
876
+ ): Promise<EncodeObject> {
877
+ return Promise.resolve(this.composer.composeMsgDepositToSpot(address, subaccountNumber, assetId, quantums));
878
+ }
879
+
880
+ async withdrawFromSpot(
881
+ subaccount: SubaccountInfo,
882
+ assetId: number,
883
+ quantums: Long,
884
+ recipient?: string,
885
+ broadcastMode?: BroadcastMode,
886
+ ): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
887
+ const msg = await this.withdrawFromSpotMsg(subaccount.address, subaccount.subaccountNumber, assetId, quantums, recipient);
888
+ return this.send(subaccount, () => Promise.resolve([msg]), false, undefined, undefined, broadcastMode);
889
+ }
890
+
891
+ async withdrawFromSpotMsg(
892
+ address: string,
893
+ subaccountNumber: number,
894
+ assetId: number,
895
+ quantums: Long,
896
+ recipient?: string,
897
+ ): Promise<EncodeObject> {
898
+ return Promise.resolve(this.composer.composeMsgWithdrawFromSpot(address, subaccountNumber, assetId, quantums, recipient));
899
+ }
900
+
760
901
  async sendToken(
761
902
  subaccount: SubaccountInfo,
762
903
  recipient: string,
@@ -188,4 +188,13 @@ export type GovAddNewMarketParams = {
188
188
  delayBlocks: number;
189
189
  };
190
190
 
191
+ /** Payload shape for MsgTransferSpotToPerp and MsgTransferPerpToSpot (spot–perp transfer). */
192
+ export interface ISpotPerpTransferMessage {
193
+ sender: string;
194
+ senderSubaccountId: { owner: string; number: number };
195
+ recipientSubaccountId: { owner: string; number: number };
196
+ assetId: number;
197
+ quantums: Long | bigint;
198
+ }
199
+
191
200
  export * from './modules/proto-includes';
@@ -8,6 +8,7 @@ import {
8
8
  ICancelOrder,
9
9
  IPlaceOrder,
10
10
  IBatchCancelOrder,
11
+ ISpotPerpTransferMessage,
11
12
  } from '../clients/types';
12
13
  import { UserError } from './errors';
13
14
 
@@ -145,6 +146,67 @@ export function validateTransferMessage(transfer: Transfer): UserError | undefin
145
146
  return undefined;
146
147
  }
147
148
 
149
+ /**
150
+ * Validates fields for MsgTransferSpotToPerp / MsgTransferPerpToSpot (spot–perp transfer).
151
+ * Checks: quantums > 0, subaccount numbers in range, sender and subaccount owners are valid Bech32.
152
+ */
153
+ function validateSpotPerpTransferMessage(
154
+ msg: ISpotPerpTransferMessage,
155
+ ): UserError | undefined {
156
+ if (!verifySubaccountNumber(msg.senderSubaccountId?.number ?? -1)) {
157
+ return new UserError(
158
+ `senderSubaccountNumber: ${msg.senderSubaccountId?.number ?? 'missing'} cannot be < 0 or > ${MAX_SUBACCOUNT_NUMBER}`,
159
+ );
160
+ }
161
+ if (!verifySubaccountNumber(msg.recipientSubaccountId?.number ?? -1)) {
162
+ return new UserError(
163
+ `recipientSubaccountNumber: ${msg.recipientSubaccountId?.number ?? 'missing'} cannot be < 0 or > ${MAX_SUBACCOUNT_NUMBER}`,
164
+ );
165
+ }
166
+ const quantumsZero =
167
+ typeof msg.quantums === 'bigint'
168
+ ? msg.quantums <= BigInt(0)
169
+ : msg.quantums.lessThanOrEqual(Long.ZERO);
170
+ if (quantumsZero) {
171
+ return new UserError(`quantums: ${msg.quantums} cannot be <= 0`);
172
+ }
173
+ const senderError = verifyIsBech32(msg.sender);
174
+ if (senderError !== undefined) {
175
+ return new UserError(senderError.toString());
176
+ }
177
+ const senderOwner = msg.senderSubaccountId?.owner;
178
+ if (senderOwner !== undefined) {
179
+ const err = verifyIsBech32(senderOwner);
180
+ if (err !== undefined) return new UserError(err.toString());
181
+ }
182
+ const recipientOwner = msg.recipientSubaccountId?.owner;
183
+ if (recipientOwner !== undefined) {
184
+ const err = verifyIsBech32(recipientOwner);
185
+ if (err !== undefined) return new UserError(err.toString());
186
+ }
187
+ return undefined;
188
+ }
189
+
190
+ /**
191
+ * @describe validateTransferSpotToPerpMessage validates that a Spot→Perp transfer message has
192
+ * fields that would be valid on-chain.
193
+ */
194
+ export function validateTransferSpotToPerpMessage(
195
+ msg: ISpotPerpTransferMessage,
196
+ ): UserError | undefined {
197
+ return validateSpotPerpTransferMessage(msg);
198
+ }
199
+
200
+ /**
201
+ * @describe validateTransferPerpToSpotMessage validates that a Perp→Spot transfer message has
202
+ * fields that would be valid on-chain.
203
+ */
204
+ export function validateTransferPerpToSpotMessage(
205
+ msg: ISpotPerpTransferMessage,
206
+ ): UserError | undefined {
207
+ return validateSpotPerpTransferMessage(msg);
208
+ }
209
+
148
210
  function verifyGoodTilBlock(goodTilBlock: number | undefined): boolean {
149
211
  if (goodTilBlock === undefined) {
150
212
  return false;