@ritbit/v4-client-js 1.3.17
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/.env +1 -0
- package/.eslintignore +2 -0
- package/.eslintrc.js +15 -0
- package/.gitleaks.toml +24 -0
- package/.gitleaksignore +1 -0
- package/.nvmrc +1 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +6 -0
- package/.releaserc +10 -0
- package/.vscode/launch.json +11 -0
- package/LICENSE +13 -0
- package/README.md +83 -0
- package/__native__/__ios__/v4-native-client.js +209891 -0
- package/__native__/__ios__/v4-native-client.js.map +1 -0
- package/__tests__/clients/composite-client.test.ts +140 -0
- package/__tests__/helpers/baseClients.ts +23 -0
- package/__tests__/helpers/constants.ts +130 -0
- package/__tests__/lib/helpers.test.ts +53 -0
- package/__tests__/lib/util.test.ts +77 -0
- package/__tests__/lib/validation.test.ts +289 -0
- package/__tests__/modules/client/AccountEndpoints.test.ts +236 -0
- package/__tests__/modules/client/FaucetEndpoint.test.ts +14 -0
- package/__tests__/modules/client/MarketsEndpoints.test.ts +84 -0
- package/__tests__/modules/client/Transfers.test.ts +44 -0
- package/__tests__/modules/client/UtilityEndpoints.test.ts +29 -0
- package/__tests__/modules/client/ValidatorGetEndpoints.test.ts +50 -0
- package/__tests__/modules/client/ValidatorPostEndpoints.test.ts +52 -0
- package/__tests__/modules/client/constants.ts +5 -0
- package/__tests__/modules/onboarding.test.ts +66 -0
- package/build/cjs/clients/composite-client.js +788 -0
- package/build/cjs/clients/constants.js +293 -0
- package/build/cjs/clients/faucet-client.js +36 -0
- package/build/cjs/clients/helpers/chain-helpers.js +178 -0
- package/build/cjs/clients/helpers/request-helpers.js +65 -0
- package/build/cjs/clients/indexer-client.js +56 -0
- package/build/cjs/clients/lib/axios/axiosRequest.js +34 -0
- package/build/cjs/clients/lib/axios/errors.js +28 -0
- package/build/cjs/clients/lib/axios/index.js +23 -0
- package/build/cjs/clients/lib/axios/types.js +11 -0
- package/build/cjs/clients/lib/cctpProto.js +3242 -0
- package/build/cjs/clients/lib/errors.js +58 -0
- package/build/cjs/clients/lib/registry.js +51 -0
- package/build/cjs/clients/modules/account.js +223 -0
- package/build/cjs/clients/modules/composer.js +404 -0
- package/build/cjs/clients/modules/get.js +469 -0
- package/build/cjs/clients/modules/local-wallet.js +59 -0
- package/build/cjs/clients/modules/markets.js +54 -0
- package/build/cjs/clients/modules/post.js +391 -0
- package/build/cjs/clients/modules/proto-includes.js +72 -0
- package/build/cjs/clients/modules/rest.js +33 -0
- package/build/cjs/clients/modules/signer.js +93 -0
- package/build/cjs/clients/modules/tendermintClient.js +137 -0
- package/build/cjs/clients/modules/utility.js +44 -0
- package/build/cjs/clients/modules/vault.js +25 -0
- package/build/cjs/clients/noble-client.js +75 -0
- package/build/cjs/clients/socket-client.js +301 -0
- package/build/cjs/clients/subaccount.js +33 -0
- package/build/cjs/clients/types.js +43 -0
- package/build/cjs/clients/validator-client.js +81 -0
- package/build/cjs/index.js +73 -0
- package/build/cjs/lib/constants.js +23 -0
- package/build/cjs/lib/errors.js +37 -0
- package/build/cjs/lib/helpers.js +98 -0
- package/build/cjs/lib/onboarding.js +75 -0
- package/build/cjs/lib/trading-key-utils.js +108 -0
- package/build/cjs/lib/utils.js +79 -0
- package/build/cjs/lib/validation.js +150 -0
- package/build/cjs/network_optimizer.js +96 -0
- package/build/cjs/package.json +1 -0
- package/build/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/build/cjs/types.js +25 -0
- package/build/esm/__tests__/clients/composite-client.test.d.ts +2 -0
- package/build/esm/__tests__/clients/composite-client.test.d.ts.map +1 -0
- package/build/esm/__tests__/clients/composite-client.test.js +128 -0
- package/build/esm/__tests__/helpers/baseClients.d.ts +19 -0
- package/build/esm/__tests__/helpers/baseClients.d.ts.map +1 -0
- package/build/esm/__tests__/helpers/baseClients.js +22 -0
- package/build/esm/__tests__/helpers/constants.d.ts +19 -0
- package/build/esm/__tests__/helpers/constants.d.ts.map +1 -0
- package/build/esm/__tests__/helpers/constants.js +104 -0
- package/build/esm/__tests__/lib/helpers.test.d.ts +2 -0
- package/build/esm/__tests__/lib/helpers.test.d.ts.map +1 -0
- package/build/esm/__tests__/lib/helpers.test.js +40 -0
- package/build/esm/__tests__/lib/util.test.d.ts +2 -0
- package/build/esm/__tests__/lib/util.test.d.ts.map +1 -0
- package/build/esm/__tests__/lib/util.test.js +65 -0
- package/build/esm/__tests__/lib/validation.test.d.ts +2 -0
- package/build/esm/__tests__/lib/validation.test.d.ts.map +1 -0
- package/build/esm/__tests__/lib/validation.test.js +249 -0
- package/build/esm/__tests__/modules/client/AccountEndpoints.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/AccountEndpoints.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/AccountEndpoints.test.js +169 -0
- package/build/esm/__tests__/modules/client/FaucetEndpoint.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/FaucetEndpoint.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/FaucetEndpoint.test.js +13 -0
- package/build/esm/__tests__/modules/client/MarketsEndpoints.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/MarketsEndpoints.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/MarketsEndpoints.test.js +66 -0
- package/build/esm/__tests__/modules/client/Transfers.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/Transfers.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/Transfers.test.js +39 -0
- package/build/esm/__tests__/modules/client/UtilityEndpoints.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/UtilityEndpoints.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/UtilityEndpoints.test.js +26 -0
- package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/ValidatorGetEndpoints.test.js +44 -0
- package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.d.ts +2 -0
- package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/ValidatorPostEndpoints.test.js +48 -0
- package/build/esm/__tests__/modules/client/constants.d.ts +4 -0
- package/build/esm/__tests__/modules/client/constants.d.ts.map +1 -0
- package/build/esm/__tests__/modules/client/constants.js +4 -0
- package/build/esm/__tests__/modules/onboarding.test.d.ts +2 -0
- package/build/esm/__tests__/modules/onboarding.test.d.ts.map +1 -0
- package/build/esm/__tests__/modules/onboarding.test.js +48 -0
- package/build/esm/examples/account_endpoints.d.ts +5 -0
- package/build/esm/examples/account_endpoints.d.ts.map +1 -0
- package/build/esm/examples/account_endpoints.js +127 -0
- package/build/esm/examples/batch_cancel_orders_example.d.ts +2 -0
- package/build/esm/examples/batch_cancel_orders_example.d.ts.map +1 -0
- package/build/esm/examples/batch_cancel_orders_example.js +88 -0
- package/build/esm/examples/composite_example.d.ts +2 -0
- package/build/esm/examples/composite_example.d.ts.map +1 -0
- package/build/esm/examples/composite_example.js +45 -0
- package/build/esm/examples/constants.d.ts +13 -0
- package/build/esm/examples/constants.d.ts.map +1 -0
- package/build/esm/examples/constants.js +29 -0
- package/build/esm/examples/faucet_endpoint.d.ts +5 -0
- package/build/esm/examples/faucet_endpoint.d.ts.map +1 -0
- package/build/esm/examples/faucet_endpoint.js +21 -0
- package/build/esm/examples/gov_add_new_market.d.ts +2 -0
- package/build/esm/examples/gov_add_new_market.d.ts.map +1 -0
- package/build/esm/examples/gov_add_new_market.js +72 -0
- package/build/esm/examples/human_readable_orders.json +86 -0
- package/build/esm/examples/human_readable_short_term_orders.json +42 -0
- package/build/esm/examples/json-encoding.d.ts +2 -0
- package/build/esm/examples/json-encoding.d.ts.map +1 -0
- package/build/esm/examples/json-encoding.js +27 -0
- package/build/esm/examples/long_term_order_cancel_example.d.ts +2 -0
- package/build/esm/examples/long_term_order_cancel_example.d.ts.map +1 -0
- package/build/esm/examples/long_term_order_cancel_example.js +58 -0
- package/build/esm/examples/markets_endpoints.d.ts +5 -0
- package/build/esm/examples/markets_endpoints.d.ts.map +1 -0
- package/build/esm/examples/markets_endpoints.js +131 -0
- package/build/esm/examples/native_examples.d.ts +2 -0
- package/build/esm/examples/native_examples.d.ts.map +1 -0
- package/build/esm/examples/native_examples.js +110 -0
- package/build/esm/examples/noble_example.d.ts +2 -0
- package/build/esm/examples/noble_example.d.ts.map +1 -0
- package/build/esm/examples/noble_example.js +83 -0
- package/build/esm/examples/optimal_node.d.ts +2 -0
- package/build/esm/examples/optimal_node.d.ts.map +1 -0
- package/build/esm/examples/optimal_node.js +68 -0
- package/build/esm/examples/permissioned_keys_example.d.ts +2 -0
- package/build/esm/examples/permissioned_keys_example.d.ts.map +1 -0
- package/build/esm/examples/permissioned_keys_example.js +99 -0
- package/build/esm/examples/raw_orders.json +130 -0
- package/build/esm/examples/short_term_order_cancel_example.d.ts +2 -0
- package/build/esm/examples/short_term_order_cancel_example.d.ts.map +1 -0
- package/build/esm/examples/short_term_order_cancel_example.js +49 -0
- package/build/esm/examples/short_term_order_composite_example.d.ts +2 -0
- package/build/esm/examples/short_term_order_composite_example.d.ts.map +1 -0
- package/build/esm/examples/short_term_order_composite_example.js +63 -0
- package/build/esm/examples/test.d.ts +2 -0
- package/build/esm/examples/test.d.ts.map +1 -0
- package/build/esm/examples/test.js +45 -0
- package/build/esm/examples/transfer_example_deposit.d.ts +2 -0
- package/build/esm/examples/transfer_example_deposit.d.ts.map +1 -0
- package/build/esm/examples/transfer_example_deposit.js +24 -0
- package/build/esm/examples/transfer_example_send.d.ts +2 -0
- package/build/esm/examples/transfer_example_send.d.ts.map +1 -0
- package/build/esm/examples/transfer_example_send.js +37 -0
- package/build/esm/examples/transfer_example_subaccount_transfer.d.ts +2 -0
- package/build/esm/examples/transfer_example_subaccount_transfer.d.ts.map +1 -0
- package/build/esm/examples/transfer_example_subaccount_transfer.js +24 -0
- package/build/esm/examples/transfer_example_withdraw.d.ts +2 -0
- package/build/esm/examples/transfer_example_withdraw.d.ts.map +1 -0
- package/build/esm/examples/transfer_example_withdraw.js +25 -0
- package/build/esm/examples/transfer_example_withdraw_other.d.ts +2 -0
- package/build/esm/examples/transfer_example_withdraw_other.d.ts.map +1 -0
- package/build/esm/examples/transfer_example_withdraw_other.js +37 -0
- package/build/esm/examples/utility_endpoints.d.ts +5 -0
- package/build/esm/examples/utility_endpoints.d.ts.map +1 -0
- package/build/esm/examples/utility_endpoints.js +40 -0
- package/build/esm/examples/validator_get_example.d.ts +2 -0
- package/build/esm/examples/validator_get_example.d.ts.map +1 -0
- package/build/esm/examples/validator_get_example.js +156 -0
- package/build/esm/examples/validator_post_example.d.ts +2 -0
- package/build/esm/examples/validator_post_example.d.ts.map +1 -0
- package/build/esm/examples/validator_post_example.js +71 -0
- package/build/esm/examples/wallet_address.d.ts +2 -0
- package/build/esm/examples/wallet_address.d.ts.map +1 -0
- package/build/esm/examples/wallet_address.js +17 -0
- package/build/esm/examples/websocket_example.d.ts +2 -0
- package/build/esm/examples/websocket_example.d.ts.map +1 -0
- package/build/esm/examples/websocket_example.js +34 -0
- package/build/esm/examples/websocket_orderbook_example.d.ts +2 -0
- package/build/esm/examples/websocket_orderbook_example.d.ts.map +1 -0
- package/build/esm/examples/websocket_orderbook_example.js +194 -0
- package/build/esm/src/clients/composite-client.d.ts +406 -0
- package/build/esm/src/clients/composite-client.d.ts.map +1 -0
- package/build/esm/src/clients/composite-client.js +781 -0
- package/build/esm/src/clients/constants.d.ts +170 -0
- package/build/esm/src/clients/constants.d.ts.map +1 -0
- package/build/esm/src/clients/constants.js +269 -0
- package/build/esm/src/clients/faucet-client.d.ts +18 -0
- package/build/esm/src/clients/faucet-client.d.ts.map +1 -0
- package/build/esm/src/clients/faucet-client.js +29 -0
- package/build/esm/src/clients/helpers/chain-helpers.d.ts +15 -0
- package/build/esm/src/clients/helpers/chain-helpers.d.ts.map +1 -0
- package/build/esm/src/clients/helpers/chain-helpers.js +163 -0
- package/build/esm/src/clients/helpers/request-helpers.d.ts +3 -0
- package/build/esm/src/clients/helpers/request-helpers.d.ts.map +1 -0
- package/build/esm/src/clients/helpers/request-helpers.js +58 -0
- package/build/esm/src/clients/indexer-client.d.ts +40 -0
- package/build/esm/src/clients/indexer-client.d.ts.map +1 -0
- package/build/esm/src/clients/indexer-client.js +49 -0
- package/build/esm/src/clients/lib/axios/axiosRequest.d.ts +9 -0
- package/build/esm/src/clients/lib/axios/axiosRequest.d.ts.map +1 -0
- package/build/esm/src/clients/lib/axios/axiosRequest.js +28 -0
- package/build/esm/src/clients/lib/axios/errors.d.ts +31 -0
- package/build/esm/src/clients/lib/axios/errors.d.ts.map +1 -0
- package/build/esm/src/clients/lib/axios/errors.js +23 -0
- package/build/esm/src/clients/lib/axios/index.d.ts +7 -0
- package/build/esm/src/clients/lib/axios/index.d.ts.map +1 -0
- package/build/esm/src/clients/lib/axios/index.js +7 -0
- package/build/esm/src/clients/lib/axios/types.d.ts +7 -0
- package/build/esm/src/clients/lib/axios/types.d.ts.map +1 -0
- package/build/esm/src/clients/lib/axios/types.js +8 -0
- package/build/esm/src/clients/lib/cctpProto.d.ts +670 -0
- package/build/esm/src/clients/lib/cctpProto.d.ts.map +1 -0
- package/build/esm/src/clients/lib/cctpProto.js +3234 -0
- package/build/esm/src/clients/lib/errors.d.ts +38 -0
- package/build/esm/src/clients/lib/errors.d.ts.map +1 -0
- package/build/esm/src/clients/lib/errors.js +50 -0
- package/build/esm/src/clients/lib/registry.d.ts +4 -0
- package/build/esm/src/clients/lib/registry.d.ts.map +1 -0
- package/build/esm/src/clients/lib/registry.js +47 -0
- package/build/esm/src/clients/modules/account.d.ts +30 -0
- package/build/esm/src/clients/modules/account.d.ts.map +1 -0
- package/build/esm/src/clients/modules/account.js +217 -0
- package/build/esm/src/clients/modules/composer.d.ts +37 -0
- package/build/esm/src/clients/modules/composer.d.ts.map +1 -0
- package/build/esm/src/clients/modules/composer.js +397 -0
- package/build/esm/src/clients/modules/get.d.ts +193 -0
- package/build/esm/src/clients/modules/get.d.ts.map +1 -0
- package/build/esm/src/clients/modules/get.js +429 -0
- package/build/esm/src/clients/modules/local-wallet.d.ts +19 -0
- package/build/esm/src/clients/modules/local-wallet.d.ts.map +1 -0
- package/build/esm/src/clients/modules/local-wallet.js +53 -0
- package/build/esm/src/clients/modules/markets.d.ts +14 -0
- package/build/esm/src/clients/modules/markets.d.ts.map +1 -0
- package/build/esm/src/clients/modules/markets.js +48 -0
- package/build/esm/src/clients/modules/post.d.ts +133 -0
- package/build/esm/src/clients/modules/post.d.ts.map +1 -0
- package/build/esm/src/clients/modules/post.js +384 -0
- package/build/esm/src/clients/modules/proto-includes.d.ts +30 -0
- package/build/esm/src/clients/modules/proto-includes.d.ts.map +1 -0
- package/build/esm/src/clients/modules/proto-includes.js +32 -0
- package/build/esm/src/clients/modules/rest.d.ts +12 -0
- package/build/esm/src/clients/modules/rest.d.ts.map +1 -0
- package/build/esm/src/clients/modules/rest.js +27 -0
- package/build/esm/src/clients/modules/signer.d.ts +19 -0
- package/build/esm/src/clients/modules/signer.d.ts.map +1 -0
- package/build/esm/src/clients/modules/signer.js +86 -0
- package/build/esm/src/clients/modules/tendermintClient.d.ts +54 -0
- package/build/esm/src/clients/modules/tendermintClient.d.ts.map +1 -0
- package/build/esm/src/clients/modules/tendermintClient.js +133 -0
- package/build/esm/src/clients/modules/utility.d.ts +27 -0
- package/build/esm/src/clients/modules/utility.d.ts.map +1 -0
- package/build/esm/src/clients/modules/utility.js +38 -0
- package/build/esm/src/clients/modules/vault.d.ts +12 -0
- package/build/esm/src/clients/modules/vault.d.ts.map +1 -0
- package/build/esm/src/clients/modules/vault.js +19 -0
- package/build/esm/src/clients/native.d.ts +75 -0
- package/build/esm/src/clients/native.d.ts.map +1 -0
- package/build/esm/src/clients/native.js +1237 -0
- package/build/esm/src/clients/noble-client.d.ts +18 -0
- package/build/esm/src/clients/noble-client.d.ts.map +1 -0
- package/build/esm/src/clients/noble-client.js +71 -0
- package/build/esm/src/clients/socket-client.d.ts +146 -0
- package/build/esm/src/clients/socket-client.d.ts.map +1 -0
- package/build/esm/src/clients/socket-client.js +294 -0
- package/build/esm/src/clients/subaccount.d.ts +14 -0
- package/build/esm/src/clients/subaccount.d.ts.map +1 -0
- package/build/esm/src/clients/subaccount.js +29 -0
- package/build/esm/src/clients/types.d.ts +137 -0
- package/build/esm/src/clients/types.d.ts.map +1 -0
- package/build/esm/src/clients/types.js +26 -0
- package/build/esm/src/clients/validator-client.d.ts +35 -0
- package/build/esm/src/clients/validator-client.d.ts.map +1 -0
- package/build/esm/src/clients/validator-client.js +74 -0
- package/build/esm/src/index.d.ts +17 -0
- package/build/esm/src/index.d.ts.map +1 -0
- package/build/esm/src/index.js +19 -0
- package/build/esm/src/lib/constants.d.ts +13 -0
- package/build/esm/src/lib/constants.d.ts.map +1 -0
- package/build/esm/src/lib/constants.js +20 -0
- package/build/esm/src/lib/errors.d.ts +23 -0
- package/build/esm/src/lib/errors.d.ts.map +1 -0
- package/build/esm/src/lib/errors.js +31 -0
- package/build/esm/src/lib/helpers.d.ts +22 -0
- package/build/esm/src/lib/helpers.d.ts.map +1 -0
- package/build/esm/src/lib/helpers.js +88 -0
- package/build/esm/src/lib/onboarding.d.ts +46 -0
- package/build/esm/src/lib/onboarding.d.ts.map +1 -0
- package/build/esm/src/lib/onboarding.js +69 -0
- package/build/esm/src/lib/trading-key-utils.d.ts +22 -0
- package/build/esm/src/lib/trading-key-utils.d.ts.map +1 -0
- package/build/esm/src/lib/trading-key-utils.js +99 -0
- package/build/esm/src/lib/utils.d.ts +39 -0
- package/build/esm/src/lib/utils.d.ts.map +1 -0
- package/build/esm/src/lib/utils.js +69 -0
- package/build/esm/src/lib/validation.d.ts +26 -0
- package/build/esm/src/lib/validation.d.ts.map +1 -0
- package/build/esm/src/lib/validation.js +138 -0
- package/build/esm/src/network_optimizer.d.ts +8 -0
- package/build/esm/src/network_optimizer.d.ts.map +1 -0
- package/build/esm/src/network_optimizer.js +91 -0
- package/build/esm/src/types.d.ts +26 -0
- package/build/esm/src/types.d.ts.map +1 -0
- package/build/esm/src/types.js +8 -0
- package/build/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/commitlint.config.js +8 -0
- package/examples/account_endpoints.ts +129 -0
- package/examples/batch_cancel_orders_example.ts +130 -0
- package/examples/composite_example.ts +65 -0
- package/examples/constants.ts +42 -0
- package/examples/faucet_endpoint.ts +24 -0
- package/examples/gov_add_new_market.json +64 -0
- package/examples/gov_add_new_market.ts +95 -0
- package/examples/human_readable_orders.json +86 -0
- package/examples/human_readable_short_term_orders.json +42 -0
- package/examples/json-encoding.ts +33 -0
- package/examples/long_term_order_cancel_example.ts +87 -0
- package/examples/markets_endpoints.ts +134 -0
- package/examples/native_examples.ts +151 -0
- package/examples/noble_example.ts +107 -0
- package/examples/optimal_node.ts +70 -0
- package/examples/permissioned_keys_example.ts +162 -0
- package/examples/raw_orders.json +130 -0
- package/examples/short_term_order_cancel_example.ts +68 -0
- package/examples/short_term_order_composite_example.ts +80 -0
- package/examples/test.ts +65 -0
- package/examples/transfer_example_deposit.ts +28 -0
- package/examples/transfer_example_send.ts +60 -0
- package/examples/transfer_example_subaccount_transfer.ts +29 -0
- package/examples/transfer_example_withdraw.ts +31 -0
- package/examples/transfer_example_withdraw_other.ts +60 -0
- package/examples/utility_endpoints.ts +42 -0
- package/examples/validator_get_example.ts +160 -0
- package/examples/validator_post_example.ts +81 -0
- package/examples/wallet_address.ts +18 -0
- package/examples/websocket_example.ts +44 -0
- package/examples/websocket_orderbook_example.ts +239 -0
- package/jest.config.js +12 -0
- package/jest.globalSetup.js +5 -0
- package/jest.setup.js +1 -0
- package/package.json +113 -0
- package/ritbit-v4-client-js-1.3.17.tgz +0 -0
- package/scripts/bump_version.sh +16 -0
- package/scripts/generate-cctp-protos.sh +41 -0
- package/scripts/mobile_build_pack.sh +5 -0
- package/scripts/publish-if-not-exists.sh +21 -0
- package/src/clients/composite-client.ts +1431 -0
- package/src/clients/constants.ts +358 -0
- package/src/clients/faucet-client.ts +48 -0
- package/src/clients/helpers/chain-helpers.ts +231 -0
- package/src/clients/helpers/request-helpers.ts +71 -0
- package/src/clients/indexer-client.ts +61 -0
- package/src/clients/lib/axios/axiosRequest.ts +41 -0
- package/src/clients/lib/axios/errors.ts +41 -0
- package/src/clients/lib/axios/index.ts +7 -0
- package/src/clients/lib/axios/types.ts +6 -0
- package/src/clients/lib/cctpProto.ts +4197 -0
- package/src/clients/lib/errors.ts +63 -0
- package/src/clients/lib/registry.ts +88 -0
- package/src/clients/modules/account.ts +388 -0
- package/src/clients/modules/composer.ts +645 -0
- package/src/clients/modules/get.ts +740 -0
- package/src/clients/modules/local-wallet.ts +79 -0
- package/src/clients/modules/markets.ts +71 -0
- package/src/clients/modules/post.ts +1016 -0
- package/src/clients/modules/proto-includes.ts +33 -0
- package/src/clients/modules/rest.ts +40 -0
- package/src/clients/modules/signer.ts +139 -0
- package/src/clients/modules/tendermintClient.ts +168 -0
- package/src/clients/modules/utility.ts +47 -0
- package/src/clients/modules/vault.ts +23 -0
- package/src/clients/native.ts +1508 -0
- package/src/clients/noble-client.ts +108 -0
- package/src/clients/socket-client.ts +331 -0
- package/src/clients/subaccount.ts +57 -0
- package/src/clients/types.ts +191 -0
- package/src/clients/validator-client.ts +103 -0
- package/src/index.ts +20 -0
- package/src/lib/constants.ts +28 -0
- package/src/lib/errors.ts +38 -0
- package/src/lib/helpers.ts +99 -0
- package/src/lib/onboarding.ts +96 -0
- package/src/lib/trading-key-utils.ts +136 -0
- package/src/lib/utils.ts +84 -0
- package/src/lib/validation.ts +197 -0
- package/src/network_optimizer.ts +132 -0
- package/src/types.ts +44 -0
- package/tasks.json +16 -0
- package/tsconfig.base.json +15 -0
- package/tsconfig.cjs.json +20 -0
- package/tsconfig.eslint.json +14 -0
- package/tsconfig.esm.json +11 -0
- package/webpack.config.js +56 -0
|
@@ -0,0 +1,1431 @@
|
|
|
1
|
+
import { EncodeObject } from '@cosmjs/proto-signing';
|
|
2
|
+
import { Account, GasPrice, IndexedTx, StdFee } from '@cosmjs/stargate';
|
|
3
|
+
import { Method, tendermint37 } from '@cosmjs/tendermint-rpc';
|
|
4
|
+
import { GetAuthenticatorsResponse } from '@ritbit/v4-proto/src/codegen/ritbit/accountplus/query';
|
|
5
|
+
import {
|
|
6
|
+
Order_ConditionType,
|
|
7
|
+
Order_TimeInForce,
|
|
8
|
+
} from '@ritbit/v4-proto/src/codegen/ritbit/clob/order';
|
|
9
|
+
import { parseUnits } from 'ethers';
|
|
10
|
+
import Long from 'long';
|
|
11
|
+
import protobuf from 'protobufjs';
|
|
12
|
+
|
|
13
|
+
type BroadcastTxAsyncResponse = tendermint37.BroadcastTxAsyncResponse;
|
|
14
|
+
type BroadcastTxSyncResponse = tendermint37.BroadcastTxSyncResponse;
|
|
15
|
+
|
|
16
|
+
import { bigIntToBytes } from '../lib/helpers';
|
|
17
|
+
import { isStatefulOrder, verifyOrderFlags } from '../lib/validation';
|
|
18
|
+
import { GovAddNewMarketParams, OrderFlags } from '../types';
|
|
19
|
+
import {
|
|
20
|
+
Authenticator,
|
|
21
|
+
AuthenticatorType,
|
|
22
|
+
Network,
|
|
23
|
+
OrderExecution,
|
|
24
|
+
OrderSide,
|
|
25
|
+
OrderTimeInForce,
|
|
26
|
+
OrderType,
|
|
27
|
+
SHORT_BLOCK_FORWARD,
|
|
28
|
+
SHORT_BLOCK_WINDOW,
|
|
29
|
+
SelectedGasDenom,
|
|
30
|
+
} from './constants';
|
|
31
|
+
import {
|
|
32
|
+
calculateQuantums,
|
|
33
|
+
calculateSubticks,
|
|
34
|
+
calculateSide,
|
|
35
|
+
calculateTimeInForce,
|
|
36
|
+
calculateOrderFlags,
|
|
37
|
+
calculateClientMetadata,
|
|
38
|
+
calculateConditionType,
|
|
39
|
+
calculateConditionalOrderTriggerSubticks,
|
|
40
|
+
calculateVaultQuantums,
|
|
41
|
+
} from './helpers/chain-helpers';
|
|
42
|
+
import { IndexerClient } from './indexer-client';
|
|
43
|
+
import { UserError } from './lib/errors';
|
|
44
|
+
import { generateRegistry } from './lib/registry';
|
|
45
|
+
import LocalWallet from './modules/local-wallet';
|
|
46
|
+
import { SubaccountInfo } from './subaccount';
|
|
47
|
+
import { BroadcastMode, OrderBatch } from './types';
|
|
48
|
+
import { ValidatorClient } from './validator-client';
|
|
49
|
+
|
|
50
|
+
// Required for encoding and decoding queries that are of type Long.
|
|
51
|
+
// Must be done once but since the individal modules should be usable
|
|
52
|
+
// - must be set in each module that encounters encoding/decoding Longs.
|
|
53
|
+
// Reference: https://github.com/protobufjs/protobuf.js/issues/921
|
|
54
|
+
protobuf.util.Long = Long;
|
|
55
|
+
protobuf.configure();
|
|
56
|
+
|
|
57
|
+
export interface MarketInfo {
|
|
58
|
+
clobPairId: number;
|
|
59
|
+
atomicResolution: number;
|
|
60
|
+
stepBaseQuantums: number;
|
|
61
|
+
quantumConversionExponent: number;
|
|
62
|
+
subticksPerTick: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface OrderBatchWithMarketId {
|
|
66
|
+
marketId: string;
|
|
67
|
+
clobPairId?: number;
|
|
68
|
+
clientIds: number[];
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type PlaceOrderPayload = {
|
|
72
|
+
subaccountNumber: number;
|
|
73
|
+
marketId: string;
|
|
74
|
+
type: OrderType;
|
|
75
|
+
side: OrderSide;
|
|
76
|
+
price: number;
|
|
77
|
+
size: number;
|
|
78
|
+
clientId: number;
|
|
79
|
+
timeInForce?: OrderTimeInForce;
|
|
80
|
+
goodTilTimeInSeconds?: number;
|
|
81
|
+
execution?: OrderExecution;
|
|
82
|
+
postOnly?: boolean;
|
|
83
|
+
reduceOnly?: boolean;
|
|
84
|
+
triggerPrice?: number;
|
|
85
|
+
marketInfo?: MarketInfo;
|
|
86
|
+
currentHeight?: number;
|
|
87
|
+
goodTilBlock?: number;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export type CancelRawOrderPayload = {
|
|
91
|
+
subaccountNumber: number;
|
|
92
|
+
clientId: number;
|
|
93
|
+
orderFlags: OrderFlags;
|
|
94
|
+
clobPairId: number;
|
|
95
|
+
goodTilBlock?: number;
|
|
96
|
+
goodTilBlockTime?: number;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export type TransferToSubaccountPayload = {
|
|
100
|
+
sourceSubaccountNumber: number;
|
|
101
|
+
recipientSubaccountNumber: number;
|
|
102
|
+
transferAmount: string;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export class CompositeClient {
|
|
106
|
+
public readonly network: Network;
|
|
107
|
+
public gasDenom: SelectedGasDenom = SelectedGasDenom.USDC;
|
|
108
|
+
private _indexerClient: IndexerClient;
|
|
109
|
+
private _validatorClient?: ValidatorClient;
|
|
110
|
+
|
|
111
|
+
static async connect(network: Network): Promise<CompositeClient> {
|
|
112
|
+
const client = new CompositeClient(network);
|
|
113
|
+
await client.initialize();
|
|
114
|
+
return client;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private constructor(network: Network, apiTimeout?: number) {
|
|
118
|
+
this.network = network;
|
|
119
|
+
this._indexerClient = new IndexerClient(network.indexerConfig, apiTimeout);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private async initialize(): Promise<void> {
|
|
123
|
+
this._validatorClient = await ValidatorClient.connect(this.network.validatorConfig);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get indexerClient(): IndexerClient {
|
|
127
|
+
/**
|
|
128
|
+
* Get the validator client
|
|
129
|
+
*/
|
|
130
|
+
return this._indexerClient!;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
get validatorClient(): ValidatorClient {
|
|
134
|
+
/**
|
|
135
|
+
* Get the validator client
|
|
136
|
+
*/
|
|
137
|
+
return this._validatorClient!;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
get selectedGasDenom(): SelectedGasDenom | undefined {
|
|
141
|
+
if (!this._validatorClient) return undefined;
|
|
142
|
+
return this._validatorClient.selectedGasDenom;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
setSelectedGasDenom(gasDenom: SelectedGasDenom): void {
|
|
146
|
+
if (!this._validatorClient) throw new Error('Validator client not initialized');
|
|
147
|
+
this._validatorClient.setSelectedGasDenom(gasDenom);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
async populateAccountNumberCache(address: string): Promise<void> {
|
|
151
|
+
if (!this._validatorClient) throw new Error('Validator client not initialized');
|
|
152
|
+
await this._validatorClient.populateAccountNumberCache(address);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* @description Sign a list of messages with a wallet.
|
|
157
|
+
* the calling function is responsible for creating the messages.
|
|
158
|
+
*
|
|
159
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
160
|
+
* at any point.
|
|
161
|
+
* @returns The Signature.
|
|
162
|
+
*/
|
|
163
|
+
async sign(
|
|
164
|
+
subaccount: SubaccountInfo,
|
|
165
|
+
messaging: () => Promise<EncodeObject[]>,
|
|
166
|
+
zeroFee: boolean,
|
|
167
|
+
gasPrice?: GasPrice,
|
|
168
|
+
memo?: string,
|
|
169
|
+
account?: () => Promise<Account>,
|
|
170
|
+
): Promise<Uint8Array> {
|
|
171
|
+
return this.validatorClient.post.sign(subaccount, messaging, zeroFee, gasPrice, memo, account);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* @description Send a list of messages with a wallet.
|
|
176
|
+
* the calling function is responsible for creating the messages.
|
|
177
|
+
*
|
|
178
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
179
|
+
* at any point.
|
|
180
|
+
* @returns The Transaction Hash.
|
|
181
|
+
*/
|
|
182
|
+
async send(
|
|
183
|
+
subaccount: SubaccountInfo,
|
|
184
|
+
messaging: () => Promise<EncodeObject[]>,
|
|
185
|
+
zeroFee: boolean,
|
|
186
|
+
gasPrice?: GasPrice,
|
|
187
|
+
memo?: string,
|
|
188
|
+
broadcastMode?: BroadcastMode,
|
|
189
|
+
account?: () => Promise<Account>,
|
|
190
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
191
|
+
return this.validatorClient.post.send(
|
|
192
|
+
subaccount,
|
|
193
|
+
messaging,
|
|
194
|
+
zeroFee,
|
|
195
|
+
gasPrice,
|
|
196
|
+
memo,
|
|
197
|
+
broadcastMode,
|
|
198
|
+
account,
|
|
199
|
+
undefined,
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @description Send a signed transaction.
|
|
205
|
+
*
|
|
206
|
+
* @param signedTransaction The signed transaction to send.
|
|
207
|
+
*
|
|
208
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
209
|
+
* at any point.
|
|
210
|
+
* @returns The Transaction Hash.
|
|
211
|
+
*/
|
|
212
|
+
async sendSignedTransaction(
|
|
213
|
+
signedTransaction: Uint8Array,
|
|
214
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
215
|
+
return this.validatorClient.post.sendSignedTransaction(signedTransaction);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @description Simulate a list of messages with a wallet.
|
|
220
|
+
* the calling function is responsible for creating the messages.
|
|
221
|
+
*
|
|
222
|
+
* To send multiple messages with gas estimate:
|
|
223
|
+
* 1. Client is responsible for creating the messages.
|
|
224
|
+
* 2. Call simulate() to get the gas estimate.
|
|
225
|
+
* 3. Call send() to send the messages.
|
|
226
|
+
*
|
|
227
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
228
|
+
* at any point.
|
|
229
|
+
* @returns The gas estimate.
|
|
230
|
+
*/
|
|
231
|
+
async simulate(
|
|
232
|
+
subaccount: SubaccountInfo,
|
|
233
|
+
messaging: () => Promise<EncodeObject[]>,
|
|
234
|
+
gasPrice?: GasPrice,
|
|
235
|
+
memo?: string,
|
|
236
|
+
account?: () => Promise<Account>,
|
|
237
|
+
): Promise<StdFee> {
|
|
238
|
+
return this.validatorClient.post.simulate(subaccount, messaging, gasPrice, memo, account);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @description Calculate the goodTilBlock value for a SHORT_TERM order
|
|
243
|
+
*
|
|
244
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
245
|
+
* at any point.
|
|
246
|
+
* @returns The goodTilBlock value
|
|
247
|
+
*/
|
|
248
|
+
|
|
249
|
+
private async calculateGoodTilBlock(
|
|
250
|
+
orderFlags: OrderFlags,
|
|
251
|
+
currentHeight?: number,
|
|
252
|
+
goodTilBlock?: number,
|
|
253
|
+
): Promise<number> {
|
|
254
|
+
if (orderFlags === OrderFlags.SHORT_TERM) {
|
|
255
|
+
if (goodTilBlock !== undefined && goodTilBlock !== 0 && goodTilBlock !== null) {
|
|
256
|
+
return Promise.resolve(goodTilBlock);
|
|
257
|
+
} else {
|
|
258
|
+
const height = currentHeight ?? (await this.validatorClient.get.latestBlockHeight());
|
|
259
|
+
return height + SHORT_BLOCK_FORWARD;
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
return Promise.resolve(0);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* @description Validate the goodTilBlock value for a SHORT_TERM order
|
|
268
|
+
*
|
|
269
|
+
* @param goodTilBlock Number of blocks from the current block height the order will
|
|
270
|
+
* be valid for.
|
|
271
|
+
*
|
|
272
|
+
* @throws UserError if the goodTilBlock value is not valid given latest block height and
|
|
273
|
+
* SHORT_BLOCK_WINDOW.
|
|
274
|
+
*/
|
|
275
|
+
private async validateGoodTilBlock(goodTilBlock: number): Promise<void> {
|
|
276
|
+
const height = await this.validatorClient.get.latestBlockHeight();
|
|
277
|
+
const nextValidBlockHeight = height + 1;
|
|
278
|
+
const lowerBound = nextValidBlockHeight;
|
|
279
|
+
const upperBound = nextValidBlockHeight + SHORT_BLOCK_WINDOW;
|
|
280
|
+
if (goodTilBlock < lowerBound || goodTilBlock > upperBound) {
|
|
281
|
+
throw new UserError(`Invalid Short-Term order GoodTilBlock.
|
|
282
|
+
Should be greater-than-or-equal-to ${lowerBound} and less-than-or-equal-to ${upperBound}.
|
|
283
|
+
Provided good til block: ${goodTilBlock}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* @description Calculate the goodTilBlockTime value for a LONG_TERM order
|
|
289
|
+
* the calling function is responsible for creating the messages.
|
|
290
|
+
*
|
|
291
|
+
* @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place.
|
|
292
|
+
*
|
|
293
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
294
|
+
* at any point.
|
|
295
|
+
* @returns The goodTilBlockTime value
|
|
296
|
+
*/
|
|
297
|
+
private calculateGoodTilBlockTime(goodTilTimeInSeconds: number): number {
|
|
298
|
+
const now = new Date();
|
|
299
|
+
const millisecondsPerSecond = 1000;
|
|
300
|
+
const interval = goodTilTimeInSeconds * millisecondsPerSecond;
|
|
301
|
+
const future = new Date(now.valueOf() + interval);
|
|
302
|
+
return Math.round(future.getTime() / 1000);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* @description Place a short term order with human readable input.
|
|
307
|
+
*
|
|
308
|
+
* Use human readable form of input, including price and size
|
|
309
|
+
* The quantum and subticks are calculated and submitted
|
|
310
|
+
*
|
|
311
|
+
* @param subaccount The subaccount to place the order under
|
|
312
|
+
* @param marketId The market to place the order on
|
|
313
|
+
* @param side The side of the order to place
|
|
314
|
+
* @param price The price of the order to place
|
|
315
|
+
* @param size The size of the order to place
|
|
316
|
+
* @param clientId The client id of the order to place
|
|
317
|
+
* @param timeInForce The time in force of the order to place
|
|
318
|
+
* @param goodTilBlock The goodTilBlock of the order to place
|
|
319
|
+
* @param reduceOnly The reduceOnly of the order to place
|
|
320
|
+
*
|
|
321
|
+
*
|
|
322
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
323
|
+
* at any point.
|
|
324
|
+
* @returns The transaction hash.
|
|
325
|
+
*/
|
|
326
|
+
async placeShortTermOrder(
|
|
327
|
+
subaccount: SubaccountInfo,
|
|
328
|
+
marketId: string,
|
|
329
|
+
side: OrderSide,
|
|
330
|
+
price: number,
|
|
331
|
+
size: number,
|
|
332
|
+
clientId: number,
|
|
333
|
+
goodTilBlock: number,
|
|
334
|
+
timeInForce: Order_TimeInForce,
|
|
335
|
+
reduceOnly: boolean,
|
|
336
|
+
memo?: string,
|
|
337
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
338
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve, reject) => {
|
|
339
|
+
const msg = this.placeShortTermOrderMessage(
|
|
340
|
+
subaccount,
|
|
341
|
+
marketId,
|
|
342
|
+
side,
|
|
343
|
+
price,
|
|
344
|
+
size,
|
|
345
|
+
clientId,
|
|
346
|
+
goodTilBlock,
|
|
347
|
+
timeInForce,
|
|
348
|
+
reduceOnly,
|
|
349
|
+
);
|
|
350
|
+
msg
|
|
351
|
+
.then((it) => {
|
|
352
|
+
resolve([it]);
|
|
353
|
+
})
|
|
354
|
+
.catch((err) => {
|
|
355
|
+
console.log(err);
|
|
356
|
+
reject(err);
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
const account: Promise<Account> = this.validatorClient.post.account(
|
|
360
|
+
subaccount.address,
|
|
361
|
+
undefined,
|
|
362
|
+
);
|
|
363
|
+
return this.send(
|
|
364
|
+
subaccount,
|
|
365
|
+
() => msgs,
|
|
366
|
+
true,
|
|
367
|
+
undefined,
|
|
368
|
+
memo,
|
|
369
|
+
undefined,
|
|
370
|
+
() => account,
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* @description Place an order with human readable input.
|
|
376
|
+
*
|
|
377
|
+
* Only MARKET and LIMIT types are supported right now
|
|
378
|
+
* Use human readable form of input, including price and size
|
|
379
|
+
* The quantum and subticks are calculated and submitted
|
|
380
|
+
*
|
|
381
|
+
* @param subaccount The subaccount to place the order on.
|
|
382
|
+
* @param marketId The market to place the order on.
|
|
383
|
+
* @param type The type of order to place.
|
|
384
|
+
* @param side The side of the order to place.
|
|
385
|
+
* @param price The price of the order to place.
|
|
386
|
+
* @param size The size of the order to place.
|
|
387
|
+
* @param clientId The client id of the order to place.
|
|
388
|
+
* @param timeInForce The time in force of the order to place.
|
|
389
|
+
* @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place.
|
|
390
|
+
* @param execution The execution of the order to place.
|
|
391
|
+
* @param postOnly The postOnly of the order to place.
|
|
392
|
+
* @param reduceOnly The reduceOnly of the order to place.
|
|
393
|
+
* @param triggerPrice The trigger price of conditional orders.
|
|
394
|
+
* @param marketInfo optional market information for calculating quantums and subticks.
|
|
395
|
+
* This can be constructed from Indexer API. If set to null, additional round
|
|
396
|
+
* trip to Indexer API will be made.
|
|
397
|
+
* @param currentHeight Current block height. This can be obtained from ValidatorClient.
|
|
398
|
+
* If set to null, additional round trip to ValidatorClient will be made.
|
|
399
|
+
*
|
|
400
|
+
*
|
|
401
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
402
|
+
* at any point.
|
|
403
|
+
* @returns The transaction hash.
|
|
404
|
+
*/
|
|
405
|
+
async placeOrder(
|
|
406
|
+
subaccount: SubaccountInfo,
|
|
407
|
+
marketId: string,
|
|
408
|
+
type: OrderType,
|
|
409
|
+
side: OrderSide,
|
|
410
|
+
price: number,
|
|
411
|
+
size: number,
|
|
412
|
+
clientId: number,
|
|
413
|
+
timeInForce?: OrderTimeInForce,
|
|
414
|
+
goodTilTimeInSeconds?: number,
|
|
415
|
+
execution?: OrderExecution,
|
|
416
|
+
postOnly?: boolean,
|
|
417
|
+
reduceOnly?: boolean,
|
|
418
|
+
triggerPrice?: number,
|
|
419
|
+
marketInfo?: MarketInfo,
|
|
420
|
+
currentHeight?: number,
|
|
421
|
+
goodTilBlock?: number,
|
|
422
|
+
memo?: string,
|
|
423
|
+
broadcastMode?: BroadcastMode,
|
|
424
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
425
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
426
|
+
const msg = this.placeOrderMessage(
|
|
427
|
+
subaccount,
|
|
428
|
+
marketId,
|
|
429
|
+
type,
|
|
430
|
+
side,
|
|
431
|
+
price,
|
|
432
|
+
size,
|
|
433
|
+
clientId,
|
|
434
|
+
timeInForce,
|
|
435
|
+
goodTilTimeInSeconds,
|
|
436
|
+
execution,
|
|
437
|
+
postOnly,
|
|
438
|
+
reduceOnly,
|
|
439
|
+
triggerPrice,
|
|
440
|
+
marketInfo,
|
|
441
|
+
currentHeight,
|
|
442
|
+
goodTilBlock,
|
|
443
|
+
);
|
|
444
|
+
msg
|
|
445
|
+
.then((it) => resolve([it]))
|
|
446
|
+
.catch((err) => {
|
|
447
|
+
throw err;
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
const orderFlags = calculateOrderFlags(type, timeInForce);
|
|
451
|
+
const account: Promise<Account> = this.validatorClient.post.account(
|
|
452
|
+
subaccount.address,
|
|
453
|
+
orderFlags,
|
|
454
|
+
);
|
|
455
|
+
return this.send(
|
|
456
|
+
subaccount,
|
|
457
|
+
() => msgs,
|
|
458
|
+
true,
|
|
459
|
+
undefined,
|
|
460
|
+
memo,
|
|
461
|
+
broadcastMode,
|
|
462
|
+
() => account,
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* @description Calculate and create the place order message
|
|
468
|
+
*
|
|
469
|
+
* Only MARKET and LIMIT types are supported right now
|
|
470
|
+
* Use human readable form of input, including price and size
|
|
471
|
+
* The quantum and subticks are calculated and submitted
|
|
472
|
+
*
|
|
473
|
+
* @param subaccount The subaccount to place the order under
|
|
474
|
+
* @param marketId The market to place the order on
|
|
475
|
+
* @param type The type of order to place
|
|
476
|
+
* @param side The side of the order to place
|
|
477
|
+
* @param price The price of the order to place
|
|
478
|
+
* @param size The size of the order to place
|
|
479
|
+
* @param clientId The client id of the order to place
|
|
480
|
+
* @param timeInForce The time in force of the order to place
|
|
481
|
+
* @param goodTilTimeInSeconds The goodTilTimeInSeconds of the order to place
|
|
482
|
+
* @param execution The execution of the order to place
|
|
483
|
+
* @param postOnly The postOnly of the order to place
|
|
484
|
+
* @param reduceOnly The reduceOnly of the order to place
|
|
485
|
+
*
|
|
486
|
+
*
|
|
487
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
488
|
+
* at any point.
|
|
489
|
+
* @returns The message to be passed into the protocol
|
|
490
|
+
*/
|
|
491
|
+
private async placeOrderMessage(
|
|
492
|
+
subaccount: SubaccountInfo,
|
|
493
|
+
marketId: string,
|
|
494
|
+
type: OrderType,
|
|
495
|
+
side: OrderSide,
|
|
496
|
+
price: number,
|
|
497
|
+
size: number,
|
|
498
|
+
clientId: number,
|
|
499
|
+
timeInForce?: OrderTimeInForce,
|
|
500
|
+
goodTilTimeInSeconds?: number,
|
|
501
|
+
execution?: OrderExecution,
|
|
502
|
+
postOnly?: boolean,
|
|
503
|
+
reduceOnly?: boolean,
|
|
504
|
+
triggerPrice?: number,
|
|
505
|
+
marketInfo?: MarketInfo,
|
|
506
|
+
currentHeight?: number,
|
|
507
|
+
goodTilBlock?: number,
|
|
508
|
+
): Promise<EncodeObject> {
|
|
509
|
+
const orderFlags = calculateOrderFlags(type, timeInForce);
|
|
510
|
+
|
|
511
|
+
const result = await Promise.all([
|
|
512
|
+
this.calculateGoodTilBlock(orderFlags, currentHeight, goodTilBlock),
|
|
513
|
+
this.retrieveMarketInfo(marketId, marketInfo),
|
|
514
|
+
]);
|
|
515
|
+
const desiredGoodTilBlock = result[0];
|
|
516
|
+
const clobPairId = result[1].clobPairId;
|
|
517
|
+
const atomicResolution = result[1].atomicResolution;
|
|
518
|
+
const stepBaseQuantums = result[1].stepBaseQuantums;
|
|
519
|
+
const quantumConversionExponent = result[1].quantumConversionExponent;
|
|
520
|
+
const subticksPerTick = result[1].subticksPerTick;
|
|
521
|
+
const orderSide = calculateSide(side);
|
|
522
|
+
const quantums = calculateQuantums(size, atomicResolution, stepBaseQuantums);
|
|
523
|
+
const subticks = calculateSubticks(
|
|
524
|
+
price,
|
|
525
|
+
atomicResolution,
|
|
526
|
+
quantumConversionExponent,
|
|
527
|
+
subticksPerTick,
|
|
528
|
+
);
|
|
529
|
+
const orderTimeInForce = calculateTimeInForce(type, timeInForce, execution, postOnly);
|
|
530
|
+
let goodTilBlockTime = 0;
|
|
531
|
+
if (orderFlags === OrderFlags.LONG_TERM || orderFlags === OrderFlags.CONDITIONAL) {
|
|
532
|
+
if (goodTilTimeInSeconds == null) {
|
|
533
|
+
throw new Error('goodTilTimeInSeconds must be set for LONG_TERM or CONDITIONAL order');
|
|
534
|
+
} else {
|
|
535
|
+
goodTilBlockTime = this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
const clientMetadata = calculateClientMetadata(type);
|
|
539
|
+
const conditionalType = calculateConditionType(type);
|
|
540
|
+
const conditionalOrderTriggerSubticks = calculateConditionalOrderTriggerSubticks(
|
|
541
|
+
type,
|
|
542
|
+
atomicResolution,
|
|
543
|
+
quantumConversionExponent,
|
|
544
|
+
subticksPerTick,
|
|
545
|
+
triggerPrice,
|
|
546
|
+
);
|
|
547
|
+
return this.validatorClient.post.composer.composeMsgPlaceOrder(
|
|
548
|
+
subaccount.address,
|
|
549
|
+
subaccount.subaccountNumber,
|
|
550
|
+
clientId,
|
|
551
|
+
clobPairId,
|
|
552
|
+
orderFlags,
|
|
553
|
+
desiredGoodTilBlock,
|
|
554
|
+
goodTilBlockTime,
|
|
555
|
+
orderSide,
|
|
556
|
+
quantums,
|
|
557
|
+
subticks,
|
|
558
|
+
orderTimeInForce,
|
|
559
|
+
reduceOnly ?? false,
|
|
560
|
+
clientMetadata,
|
|
561
|
+
conditionalType,
|
|
562
|
+
conditionalOrderTriggerSubticks,
|
|
563
|
+
);
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
private async retrieveMarketInfo(marketId: string, marketInfo?: MarketInfo): Promise<MarketInfo> {
|
|
567
|
+
if (marketInfo) {
|
|
568
|
+
return Promise.resolve(marketInfo);
|
|
569
|
+
} else {
|
|
570
|
+
const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
|
|
571
|
+
const market = marketsResponse.markets[marketId];
|
|
572
|
+
const clobPairId = market.clobPairId;
|
|
573
|
+
const atomicResolution = market.atomicResolution;
|
|
574
|
+
const stepBaseQuantums = market.stepBaseQuantums;
|
|
575
|
+
const quantumConversionExponent = market.quantumConversionExponent;
|
|
576
|
+
const subticksPerTick = market.subticksPerTick;
|
|
577
|
+
return {
|
|
578
|
+
clobPairId,
|
|
579
|
+
atomicResolution,
|
|
580
|
+
stepBaseQuantums,
|
|
581
|
+
quantumConversionExponent,
|
|
582
|
+
subticksPerTick,
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* @description Calculate and create the short term place order message
|
|
589
|
+
*
|
|
590
|
+
* Use human readable form of input, including price and size
|
|
591
|
+
* The quantum and subticks are calculated and submitted
|
|
592
|
+
*
|
|
593
|
+
* @param subaccount The subaccount to place the order under
|
|
594
|
+
* @param marketId The market to place the order on
|
|
595
|
+
* @param side The side of the order to place
|
|
596
|
+
* @param price The price of the order to place
|
|
597
|
+
* @param size The size of the order to place
|
|
598
|
+
* @param clientId The client id of the order to place
|
|
599
|
+
* @param timeInForce The time in force of the order to place
|
|
600
|
+
* @param goodTilBlock The goodTilBlock of the order to place
|
|
601
|
+
* @param reduceOnly The reduceOnly of the order to place
|
|
602
|
+
*
|
|
603
|
+
*
|
|
604
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
605
|
+
* at any point.
|
|
606
|
+
* @returns The message to be passed into the protocol
|
|
607
|
+
*/
|
|
608
|
+
private async placeShortTermOrderMessage(
|
|
609
|
+
subaccount: SubaccountInfo,
|
|
610
|
+
marketId: string,
|
|
611
|
+
side: OrderSide,
|
|
612
|
+
price: number,
|
|
613
|
+
size: number,
|
|
614
|
+
clientId: number,
|
|
615
|
+
goodTilBlock: number,
|
|
616
|
+
timeInForce: Order_TimeInForce,
|
|
617
|
+
reduceOnly: boolean,
|
|
618
|
+
): Promise<EncodeObject> {
|
|
619
|
+
await this.validateGoodTilBlock(goodTilBlock);
|
|
620
|
+
|
|
621
|
+
const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
|
|
622
|
+
const market = marketsResponse.markets[marketId];
|
|
623
|
+
const clobPairId = market.clobPairId;
|
|
624
|
+
const atomicResolution = market.atomicResolution;
|
|
625
|
+
const stepBaseQuantums = market.stepBaseQuantums;
|
|
626
|
+
const quantumConversionExponent = market.quantumConversionExponent;
|
|
627
|
+
const subticksPerTick = market.subticksPerTick;
|
|
628
|
+
const orderSide = calculateSide(side);
|
|
629
|
+
const quantums = calculateQuantums(size, atomicResolution, stepBaseQuantums);
|
|
630
|
+
const subticks = calculateSubticks(
|
|
631
|
+
price,
|
|
632
|
+
atomicResolution,
|
|
633
|
+
quantumConversionExponent,
|
|
634
|
+
subticksPerTick,
|
|
635
|
+
);
|
|
636
|
+
const orderFlags = OrderFlags.SHORT_TERM;
|
|
637
|
+
return this.validatorClient.post.composer.composeMsgPlaceOrder(
|
|
638
|
+
subaccount.address,
|
|
639
|
+
subaccount.subaccountNumber,
|
|
640
|
+
clientId,
|
|
641
|
+
clobPairId,
|
|
642
|
+
orderFlags,
|
|
643
|
+
goodTilBlock,
|
|
644
|
+
0, // Short term orders use goodTilBlock.
|
|
645
|
+
orderSide,
|
|
646
|
+
quantums,
|
|
647
|
+
subticks,
|
|
648
|
+
timeInForce,
|
|
649
|
+
reduceOnly,
|
|
650
|
+
0, // Client metadata is 0 for short term orders.
|
|
651
|
+
Order_ConditionType.CONDITION_TYPE_UNSPECIFIED, // Short term orders cannot be conditional.
|
|
652
|
+
Long.fromInt(0), // Short term orders cannot be conditional.
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* @description Cancel an order with order information from web socket or REST.
|
|
658
|
+
*
|
|
659
|
+
* @param subaccount The subaccount to cancel the order from
|
|
660
|
+
* @param clientId The client id of the order to cancel
|
|
661
|
+
* @param orderFlags The order flags of the order to cancel
|
|
662
|
+
* @param clobPairId The clob pair id of the order to cancel
|
|
663
|
+
* @param goodTilBlock The goodTilBlock of the order to cancel
|
|
664
|
+
* @param goodTilBlockTime The goodTilBlockTime of the order to cancel
|
|
665
|
+
*
|
|
666
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
667
|
+
* at any point.
|
|
668
|
+
* @returns The transaction hash.
|
|
669
|
+
*/
|
|
670
|
+
async cancelRawOrder(
|
|
671
|
+
subaccount: SubaccountInfo,
|
|
672
|
+
clientId: number,
|
|
673
|
+
orderFlags: OrderFlags,
|
|
674
|
+
clobPairId: number,
|
|
675
|
+
goodTilBlock?: number,
|
|
676
|
+
goodTilBlockTime?: number,
|
|
677
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
678
|
+
return this.validatorClient.post.cancelOrder(
|
|
679
|
+
subaccount,
|
|
680
|
+
clientId,
|
|
681
|
+
orderFlags,
|
|
682
|
+
clobPairId,
|
|
683
|
+
goodTilBlock,
|
|
684
|
+
goodTilBlockTime,
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* @description Cancel an order with human readable input.
|
|
690
|
+
*
|
|
691
|
+
* @param subaccount The subaccount to cancel the order from
|
|
692
|
+
* @param clientId The client id of the order to cancel
|
|
693
|
+
* @param orderFlags The order flags of the order to cancel
|
|
694
|
+
* @param marketId The market to cancel the order on
|
|
695
|
+
* @param goodTilBlock The goodTilBlock of the order to cancel
|
|
696
|
+
* @param goodTilBlockTime The goodTilBlockTime of the order to cancel
|
|
697
|
+
*
|
|
698
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
699
|
+
* at any point.
|
|
700
|
+
* @returns The transaction hash.
|
|
701
|
+
*/
|
|
702
|
+
async cancelOrder(
|
|
703
|
+
subaccount: SubaccountInfo,
|
|
704
|
+
clientId: number,
|
|
705
|
+
orderFlags: OrderFlags,
|
|
706
|
+
marketId: string,
|
|
707
|
+
goodTilBlock?: number,
|
|
708
|
+
goodTilTimeInSeconds?: number,
|
|
709
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
710
|
+
const marketsResponse = await this.indexerClient.markets.getPerpetualMarkets(marketId);
|
|
711
|
+
const market = marketsResponse.markets[marketId];
|
|
712
|
+
const clobPairId = market.clobPairId;
|
|
713
|
+
|
|
714
|
+
if (!verifyOrderFlags(orderFlags)) {
|
|
715
|
+
throw new Error(`Invalid order flags: ${orderFlags}`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
let goodTilBlockTime;
|
|
719
|
+
if (isStatefulOrder(orderFlags)) {
|
|
720
|
+
if (goodTilTimeInSeconds === undefined || goodTilTimeInSeconds === 0) {
|
|
721
|
+
throw new Error('goodTilTimeInSeconds must be set for LONG_TERM or CONDITIONAL order');
|
|
722
|
+
}
|
|
723
|
+
if (goodTilBlock !== 0) {
|
|
724
|
+
throw new Error(
|
|
725
|
+
'goodTilBlock should be zero since LONG_TERM or CONDITIONAL orders ' +
|
|
726
|
+
'use goodTilTimeInSeconds instead of goodTilBlock.',
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
goodTilBlockTime = this.calculateGoodTilBlockTime(goodTilTimeInSeconds);
|
|
730
|
+
} else {
|
|
731
|
+
if (goodTilBlock === undefined || goodTilBlock === 0) {
|
|
732
|
+
throw new Error('goodTilBlock must be non-zero for SHORT_TERM orders');
|
|
733
|
+
}
|
|
734
|
+
if (goodTilTimeInSeconds !== undefined && goodTilTimeInSeconds !== 0) {
|
|
735
|
+
throw new Error(
|
|
736
|
+
'goodTilTimeInSeconds should be zero since SHORT_TERM orders use goodTilBlock instead of goodTilTimeInSeconds.',
|
|
737
|
+
);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return this.validatorClient.post.cancelOrder(
|
|
742
|
+
subaccount,
|
|
743
|
+
clientId,
|
|
744
|
+
orderFlags,
|
|
745
|
+
clobPairId,
|
|
746
|
+
goodTilBlock,
|
|
747
|
+
goodTilBlockTime,
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* @description Batch cancel short term orders using marketId to clobPairId translation.
|
|
753
|
+
*
|
|
754
|
+
* @param subaccount The subaccount to cancel the order from
|
|
755
|
+
* @param shortTermOrders The list of short term order batches to cancel with marketId
|
|
756
|
+
* @param goodTilBlock The goodTilBlock of the order to cancel
|
|
757
|
+
* @returns The transaction hash.
|
|
758
|
+
*/
|
|
759
|
+
async batchCancelShortTermOrdersWithMarketId(
|
|
760
|
+
subaccount: SubaccountInfo,
|
|
761
|
+
shortTermOrders: OrderBatchWithMarketId[],
|
|
762
|
+
goodTilBlock: number,
|
|
763
|
+
broadcastMode?: BroadcastMode,
|
|
764
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
765
|
+
const orderBatches = await Promise.all(
|
|
766
|
+
shortTermOrders.map(async ({ marketId, clobPairId, clientIds }) => ({
|
|
767
|
+
clobPairId: (
|
|
768
|
+
clobPairId ??
|
|
769
|
+
(await this.indexerClient.markets.getPerpetualMarkets(marketId)).markets[marketId]
|
|
770
|
+
).clobPairId,
|
|
771
|
+
clientIds,
|
|
772
|
+
})),
|
|
773
|
+
);
|
|
774
|
+
|
|
775
|
+
return this.validatorClient.post.batchCancelShortTermOrders(
|
|
776
|
+
subaccount,
|
|
777
|
+
orderBatches,
|
|
778
|
+
goodTilBlock,
|
|
779
|
+
broadcastMode,
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
/**
|
|
784
|
+
* @description Batch cancel short term orders using clobPairId.
|
|
785
|
+
*
|
|
786
|
+
* @param subaccount The subaccount to cancel the order from
|
|
787
|
+
* @param shortTermOrders The list of short term order batches to cancel with clobPairId
|
|
788
|
+
* @param goodTilBlock The goodTilBlock of the order to cancel
|
|
789
|
+
* @returns The transaction hash.
|
|
790
|
+
*/
|
|
791
|
+
async batchCancelShortTermOrdersWithClobPairId(
|
|
792
|
+
subaccount: SubaccountInfo,
|
|
793
|
+
shortTermOrders: OrderBatch[],
|
|
794
|
+
goodTilBlock: number,
|
|
795
|
+
broadcastMode?: BroadcastMode,
|
|
796
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
797
|
+
return this.validatorClient.post.batchCancelShortTermOrders(
|
|
798
|
+
subaccount,
|
|
799
|
+
shortTermOrders,
|
|
800
|
+
goodTilBlock,
|
|
801
|
+
broadcastMode,
|
|
802
|
+
);
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* @description Transfer from a subaccount to another subaccount
|
|
807
|
+
*
|
|
808
|
+
* @param subaccount The subaccount to transfer from
|
|
809
|
+
* @param recipientAddress The recipient address
|
|
810
|
+
* @param recipientSubaccountNumber The recipient subaccount number
|
|
811
|
+
* @param amount The amount to transfer
|
|
812
|
+
*
|
|
813
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
814
|
+
* at any point.
|
|
815
|
+
* @returns The transaction hash.
|
|
816
|
+
*/
|
|
817
|
+
async transferToSubaccount(
|
|
818
|
+
subaccount: SubaccountInfo,
|
|
819
|
+
recipientAddress: string,
|
|
820
|
+
recipientSubaccountNumber: number,
|
|
821
|
+
amount: string,
|
|
822
|
+
memo?: string,
|
|
823
|
+
broadcastMode?: BroadcastMode,
|
|
824
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
825
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
826
|
+
const msg = this.transferToSubaccountMessage(
|
|
827
|
+
subaccount,
|
|
828
|
+
recipientAddress,
|
|
829
|
+
recipientSubaccountNumber,
|
|
830
|
+
amount,
|
|
831
|
+
);
|
|
832
|
+
resolve([msg]);
|
|
833
|
+
});
|
|
834
|
+
return this.send(
|
|
835
|
+
subaccount,
|
|
836
|
+
() => msgs,
|
|
837
|
+
false,
|
|
838
|
+
undefined,
|
|
839
|
+
memo,
|
|
840
|
+
broadcastMode ?? Method.BroadcastTxCommit,
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* @description Create message to transfer from a subaccount to another subaccount
|
|
846
|
+
*
|
|
847
|
+
* @param subaccount The subaccount to transfer from
|
|
848
|
+
* @param recipientAddress The recipient address
|
|
849
|
+
* @param recipientSubaccountNumber The recipient subaccount number
|
|
850
|
+
* @param amount The amount to transfer
|
|
851
|
+
*
|
|
852
|
+
*
|
|
853
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
854
|
+
* at any point.
|
|
855
|
+
* @returns The message
|
|
856
|
+
*/
|
|
857
|
+
transferToSubaccountMessage(
|
|
858
|
+
subaccount: SubaccountInfo,
|
|
859
|
+
recipientAddress: string,
|
|
860
|
+
recipientSubaccountNumber: number,
|
|
861
|
+
amount: string,
|
|
862
|
+
): EncodeObject {
|
|
863
|
+
const validatorClient = this._validatorClient;
|
|
864
|
+
if (validatorClient === undefined) {
|
|
865
|
+
throw new Error('validatorClient not set');
|
|
866
|
+
}
|
|
867
|
+
const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
|
|
868
|
+
if (quantums > BigInt(Long.MAX_VALUE.toString())) {
|
|
869
|
+
throw new Error('amount to large');
|
|
870
|
+
}
|
|
871
|
+
if (quantums < 0) {
|
|
872
|
+
throw new Error('amount must be positive');
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
return this.validatorClient.post.composer.composeMsgTransfer(
|
|
876
|
+
subaccount.address,
|
|
877
|
+
subaccount.subaccountNumber,
|
|
878
|
+
recipientAddress,
|
|
879
|
+
recipientSubaccountNumber,
|
|
880
|
+
0,
|
|
881
|
+
Long.fromString(quantums.toString()),
|
|
882
|
+
);
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* @description Deposit from wallet to subaccount
|
|
887
|
+
*
|
|
888
|
+
* @param subaccount The subaccount to deposit to
|
|
889
|
+
* @param amount The amount to deposit
|
|
890
|
+
*
|
|
891
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
892
|
+
* at any point.
|
|
893
|
+
* @returns The transaction hash.
|
|
894
|
+
*/
|
|
895
|
+
async depositToSubaccount(
|
|
896
|
+
subaccount: SubaccountInfo,
|
|
897
|
+
amount: string,
|
|
898
|
+
memo?: string,
|
|
899
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
900
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
901
|
+
const msg = this.depositToSubaccountMessage(subaccount, amount);
|
|
902
|
+
resolve([msg]);
|
|
903
|
+
});
|
|
904
|
+
return this.validatorClient.post.send(subaccount, () => msgs, false, undefined, memo);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* @description Create message to deposit from wallet to subaccount
|
|
909
|
+
*
|
|
910
|
+
* @param subaccount The subaccount to deposit to
|
|
911
|
+
* @param amount The amount to deposit
|
|
912
|
+
*
|
|
913
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
914
|
+
* at any point.
|
|
915
|
+
* @returns The message
|
|
916
|
+
*/
|
|
917
|
+
depositToSubaccountMessage(subaccount: SubaccountInfo, amount: string): EncodeObject {
|
|
918
|
+
const validatorClient = this._validatorClient;
|
|
919
|
+
if (validatorClient === undefined) {
|
|
920
|
+
throw new Error('validatorClient not set');
|
|
921
|
+
}
|
|
922
|
+
const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
|
|
923
|
+
if (quantums > BigInt(Long.MAX_VALUE.toString())) {
|
|
924
|
+
throw new Error('amount to large');
|
|
925
|
+
}
|
|
926
|
+
if (quantums < 0) {
|
|
927
|
+
throw new Error('amount must be positive');
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
return this.validatorClient.post.composer.composeMsgDepositToSubaccount(
|
|
931
|
+
subaccount.address,
|
|
932
|
+
subaccount.subaccountNumber,
|
|
933
|
+
0,
|
|
934
|
+
Long.fromString(quantums.toString()),
|
|
935
|
+
);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
/**
|
|
939
|
+
* @description Withdraw from subaccount to wallet
|
|
940
|
+
*
|
|
941
|
+
* @param subaccount The subaccount to withdraw from
|
|
942
|
+
* @param amount The amount to withdraw
|
|
943
|
+
* @param recipient The recipient address, default to subaccount address
|
|
944
|
+
*
|
|
945
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
946
|
+
* at any point.
|
|
947
|
+
* @returns The transaction hash
|
|
948
|
+
*/
|
|
949
|
+
async withdrawFromSubaccount(
|
|
950
|
+
subaccount: SubaccountInfo,
|
|
951
|
+
amount: string,
|
|
952
|
+
recipient?: string,
|
|
953
|
+
memo?: string,
|
|
954
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
955
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
956
|
+
const msg = this.withdrawFromSubaccountMessage(subaccount, amount, recipient);
|
|
957
|
+
resolve([msg]);
|
|
958
|
+
});
|
|
959
|
+
return this.send(subaccount, () => msgs, false, undefined, memo);
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* @description Create message to withdraw from subaccount to wallet
|
|
964
|
+
* with human readable input.
|
|
965
|
+
*
|
|
966
|
+
* @param subaccount The subaccount to withdraw from
|
|
967
|
+
* @param amount The amount to withdraw
|
|
968
|
+
* @param recipient The recipient address
|
|
969
|
+
*
|
|
970
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
971
|
+
* at any point.
|
|
972
|
+
* @returns The message
|
|
973
|
+
*/
|
|
974
|
+
withdrawFromSubaccountMessage(
|
|
975
|
+
subaccount: SubaccountInfo,
|
|
976
|
+
amount: string,
|
|
977
|
+
recipient?: string,
|
|
978
|
+
): EncodeObject {
|
|
979
|
+
const validatorClient = this._validatorClient;
|
|
980
|
+
if (validatorClient === undefined) {
|
|
981
|
+
throw new Error('validatorClient not set');
|
|
982
|
+
}
|
|
983
|
+
const quantums = parseUnits(amount, validatorClient.config.denoms.USDC_DECIMALS);
|
|
984
|
+
if (quantums > BigInt(Long.MAX_VALUE.toString())) {
|
|
985
|
+
throw new Error('amount to large');
|
|
986
|
+
}
|
|
987
|
+
if (quantums < 0) {
|
|
988
|
+
throw new Error('amount must be positive');
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
return this.validatorClient.post.composer.composeMsgWithdrawFromSubaccount(
|
|
992
|
+
subaccount.address,
|
|
993
|
+
subaccount.subaccountNumber,
|
|
994
|
+
0,
|
|
995
|
+
Long.fromString(quantums.toString()),
|
|
996
|
+
recipient,
|
|
997
|
+
);
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
/**
|
|
1001
|
+
* @description Create message to send chain token from subaccount to wallet
|
|
1002
|
+
* with human readable input.
|
|
1003
|
+
*
|
|
1004
|
+
* @param subaccount The subaccount to withdraw from
|
|
1005
|
+
* @param amount The amount to withdraw
|
|
1006
|
+
* @param recipient The recipient address
|
|
1007
|
+
*
|
|
1008
|
+
* @throws UnexpectedClientError if a malformed response is returned with no GRPC error
|
|
1009
|
+
* at any point.
|
|
1010
|
+
* @returns The message
|
|
1011
|
+
*/
|
|
1012
|
+
sendTokenMessage(wallet: LocalWallet, amount: string, recipient: string): EncodeObject {
|
|
1013
|
+
const address = wallet.address;
|
|
1014
|
+
if (address === undefined) {
|
|
1015
|
+
throw new UserError('wallet address is not set. Call connectWallet() first');
|
|
1016
|
+
}
|
|
1017
|
+
const { CHAINTOKEN_DENOM: chainTokenDenom, CHAINTOKEN_DECIMALS: chainTokenDecimals } =
|
|
1018
|
+
this._validatorClient?.config.denoms || {};
|
|
1019
|
+
|
|
1020
|
+
if (chainTokenDenom === undefined || chainTokenDecimals === undefined) {
|
|
1021
|
+
throw new Error('Chain token denom not set in validator config');
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
const quantums = parseUnits(amount, chainTokenDecimals);
|
|
1025
|
+
|
|
1026
|
+
return this.validatorClient.post.composer.composeMsgSendToken(
|
|
1027
|
+
address,
|
|
1028
|
+
recipient,
|
|
1029
|
+
chainTokenDenom,
|
|
1030
|
+
quantums.toString(),
|
|
1031
|
+
);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
async signPlaceOrder(
|
|
1035
|
+
subaccount: SubaccountInfo,
|
|
1036
|
+
marketId: string,
|
|
1037
|
+
type: OrderType,
|
|
1038
|
+
side: OrderSide,
|
|
1039
|
+
price: number,
|
|
1040
|
+
// trigger_price: number, // not used for MARKET and LIMIT
|
|
1041
|
+
size: number,
|
|
1042
|
+
clientId: number,
|
|
1043
|
+
timeInForce: OrderTimeInForce,
|
|
1044
|
+
goodTilTimeInSeconds: number,
|
|
1045
|
+
execution: OrderExecution,
|
|
1046
|
+
postOnly: boolean,
|
|
1047
|
+
reduceOnly: boolean,
|
|
1048
|
+
): Promise<string> {
|
|
1049
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
1050
|
+
const msg = this.placeOrderMessage(
|
|
1051
|
+
subaccount,
|
|
1052
|
+
marketId,
|
|
1053
|
+
type,
|
|
1054
|
+
side,
|
|
1055
|
+
price,
|
|
1056
|
+
// trigger_price: number, // not used for MARKET and LIMIT
|
|
1057
|
+
size,
|
|
1058
|
+
clientId,
|
|
1059
|
+
timeInForce,
|
|
1060
|
+
goodTilTimeInSeconds,
|
|
1061
|
+
execution,
|
|
1062
|
+
postOnly,
|
|
1063
|
+
reduceOnly,
|
|
1064
|
+
);
|
|
1065
|
+
msg
|
|
1066
|
+
.then((it) => resolve([it]))
|
|
1067
|
+
.catch((err) => {
|
|
1068
|
+
console.log(err);
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
const signature = await this.sign(subaccount, () => msgs, true);
|
|
1072
|
+
|
|
1073
|
+
return Buffer.from(signature).toString('base64');
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
async signCancelOrder(
|
|
1077
|
+
subaccount: SubaccountInfo,
|
|
1078
|
+
clientId: number,
|
|
1079
|
+
orderFlags: OrderFlags,
|
|
1080
|
+
clobPairId: number,
|
|
1081
|
+
goodTilBlock: number,
|
|
1082
|
+
goodTilBlockTime: number,
|
|
1083
|
+
): Promise<string> {
|
|
1084
|
+
const msgs: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
1085
|
+
const msg = this.validatorClient.post.composer.composeMsgCancelOrder(
|
|
1086
|
+
subaccount.address,
|
|
1087
|
+
subaccount.subaccountNumber,
|
|
1088
|
+
clientId,
|
|
1089
|
+
clobPairId,
|
|
1090
|
+
orderFlags,
|
|
1091
|
+
goodTilBlock,
|
|
1092
|
+
goodTilBlockTime,
|
|
1093
|
+
);
|
|
1094
|
+
resolve([msg]);
|
|
1095
|
+
});
|
|
1096
|
+
const signature = await this.sign(subaccount, () => msgs, true);
|
|
1097
|
+
|
|
1098
|
+
return Buffer.from(signature).toString('base64');
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
async bulkCancelAndTransferAndPlaceStatefulOrders(
|
|
1102
|
+
subaccount: SubaccountInfo,
|
|
1103
|
+
// these are executed in this order, all in one block, and all succeed or all fail
|
|
1104
|
+
cancelOrderPayloads: CancelRawOrderPayload[],
|
|
1105
|
+
transferToSubaccountPayload: TransferToSubaccountPayload | undefined,
|
|
1106
|
+
placeOrderPayloads: PlaceOrderPayload[],
|
|
1107
|
+
memo?: string,
|
|
1108
|
+
broadcastMode?: BroadcastMode,
|
|
1109
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1110
|
+
if (cancelOrderPayloads.some((c) => c.orderFlags === OrderFlags.SHORT_TERM)) {
|
|
1111
|
+
throw new Error('SHORT_TERM cancels cannot be batched');
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
if (
|
|
1115
|
+
placeOrderPayloads.some(
|
|
1116
|
+
(placePayload) =>
|
|
1117
|
+
calculateOrderFlags(placePayload.type, placePayload.timeInForce) ===
|
|
1118
|
+
OrderFlags.SHORT_TERM,
|
|
1119
|
+
)
|
|
1120
|
+
) {
|
|
1121
|
+
throw new Error('SHORT_TERM orders cannot be batched');
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
const account: Promise<Account> = this.validatorClient.post.account(
|
|
1125
|
+
subaccount.address,
|
|
1126
|
+
undefined,
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1129
|
+
const msgs: Promise<EncodeObject[]> = (async () => {
|
|
1130
|
+
const cancelMsgPromises = cancelOrderPayloads.map(async (cancelPayload) => {
|
|
1131
|
+
const cancelSubaccount = subaccount.cloneWithSubaccount(cancelPayload.subaccountNumber);
|
|
1132
|
+
return this.validatorClient.post.cancelOrderMsg(
|
|
1133
|
+
cancelSubaccount.address,
|
|
1134
|
+
cancelSubaccount.subaccountNumber,
|
|
1135
|
+
cancelPayload.clientId,
|
|
1136
|
+
cancelPayload.orderFlags,
|
|
1137
|
+
cancelPayload.clobPairId,
|
|
1138
|
+
cancelPayload.goodTilBlock,
|
|
1139
|
+
cancelPayload.goodTilBlockTime,
|
|
1140
|
+
);
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
const transferMsg = (() => {
|
|
1144
|
+
if (transferToSubaccountPayload == null) {
|
|
1145
|
+
return undefined;
|
|
1146
|
+
}
|
|
1147
|
+
const transferSubaccount = subaccount.cloneWithSubaccount(
|
|
1148
|
+
transferToSubaccountPayload.sourceSubaccountNumber,
|
|
1149
|
+
);
|
|
1150
|
+
return this.transferToSubaccountMessage(
|
|
1151
|
+
transferSubaccount,
|
|
1152
|
+
transferSubaccount.address,
|
|
1153
|
+
transferToSubaccountPayload.recipientSubaccountNumber,
|
|
1154
|
+
transferToSubaccountPayload.transferAmount,
|
|
1155
|
+
);
|
|
1156
|
+
})();
|
|
1157
|
+
|
|
1158
|
+
const placeOrderMsgPromises = placeOrderPayloads.map((placePayload) => {
|
|
1159
|
+
const placeSubaccount = subaccount.cloneWithSubaccount(placePayload.subaccountNumber);
|
|
1160
|
+
return this.placeOrderMessage(
|
|
1161
|
+
placeSubaccount,
|
|
1162
|
+
placePayload.marketId,
|
|
1163
|
+
placePayload.type,
|
|
1164
|
+
placePayload.side,
|
|
1165
|
+
placePayload.price,
|
|
1166
|
+
placePayload.size,
|
|
1167
|
+
placePayload.clientId,
|
|
1168
|
+
placePayload.timeInForce,
|
|
1169
|
+
placePayload.goodTilTimeInSeconds,
|
|
1170
|
+
placePayload.execution,
|
|
1171
|
+
placePayload.postOnly,
|
|
1172
|
+
placePayload.reduceOnly,
|
|
1173
|
+
placePayload.triggerPrice,
|
|
1174
|
+
placePayload.marketInfo,
|
|
1175
|
+
placePayload.currentHeight,
|
|
1176
|
+
placePayload.goodTilBlock,
|
|
1177
|
+
);
|
|
1178
|
+
});
|
|
1179
|
+
|
|
1180
|
+
return Promise.all([
|
|
1181
|
+
...cancelMsgPromises,
|
|
1182
|
+
...(transferMsg != null ? [transferMsg] : []),
|
|
1183
|
+
...placeOrderMsgPromises,
|
|
1184
|
+
]);
|
|
1185
|
+
})();
|
|
1186
|
+
|
|
1187
|
+
return this.send(
|
|
1188
|
+
subaccount,
|
|
1189
|
+
() => msgs,
|
|
1190
|
+
true,
|
|
1191
|
+
undefined,
|
|
1192
|
+
memo,
|
|
1193
|
+
broadcastMode ?? Method.BroadcastTxCommit,
|
|
1194
|
+
() => account,
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
// vaults
|
|
1199
|
+
|
|
1200
|
+
async depositToMegavault(
|
|
1201
|
+
subaccount: SubaccountInfo,
|
|
1202
|
+
amountUsdc: number,
|
|
1203
|
+
broadcastMode?: BroadcastMode,
|
|
1204
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1205
|
+
return this.validatorClient.post.depositToMegavault(
|
|
1206
|
+
subaccount,
|
|
1207
|
+
bigIntToBytes(calculateVaultQuantums(amountUsdc)),
|
|
1208
|
+
broadcastMode,
|
|
1209
|
+
);
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
depositToMegavaultMessage(subaccount: SubaccountInfo, amountUsdc: number): EncodeObject {
|
|
1213
|
+
return this.validatorClient.post.depositToMegavaultMsg(
|
|
1214
|
+
subaccount.address,
|
|
1215
|
+
subaccount.subaccountNumber,
|
|
1216
|
+
bigIntToBytes(calculateVaultQuantums(amountUsdc)),
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
async withdrawFromMegavault(
|
|
1221
|
+
subaccount: SubaccountInfo,
|
|
1222
|
+
shares: number,
|
|
1223
|
+
minAmount: number,
|
|
1224
|
+
broadcastMode?: BroadcastMode,
|
|
1225
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1226
|
+
return this.validatorClient.post.withdrawFromMegavault(
|
|
1227
|
+
subaccount,
|
|
1228
|
+
bigIntToBytes(BigInt(Math.floor(shares))),
|
|
1229
|
+
bigIntToBytes(calculateVaultQuantums(minAmount)),
|
|
1230
|
+
broadcastMode,
|
|
1231
|
+
);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
withdrawFromMegavaultMessage(
|
|
1235
|
+
subaccount: SubaccountInfo,
|
|
1236
|
+
shares: number,
|
|
1237
|
+
minAmount: number,
|
|
1238
|
+
): EncodeObject {
|
|
1239
|
+
return this.validatorClient.post.withdrawFromMegavaultMsg(
|
|
1240
|
+
subaccount.address,
|
|
1241
|
+
subaccount.subaccountNumber,
|
|
1242
|
+
bigIntToBytes(BigInt(Math.floor(shares))),
|
|
1243
|
+
bigIntToBytes(calculateVaultQuantums(minAmount)),
|
|
1244
|
+
);
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
/**
|
|
1248
|
+
* @description Submit a governance proposal to add a new market.
|
|
1249
|
+
*
|
|
1250
|
+
* @param params Parameters neeeded to create a new market.
|
|
1251
|
+
* @param title Title of the gov proposal.
|
|
1252
|
+
* @param summary Summary of the gov proposal.
|
|
1253
|
+
* @param initialDepositAmount Initial deposit amount of the gov proposal.
|
|
1254
|
+
* @param proposer proposer of the gov proposal.
|
|
1255
|
+
*
|
|
1256
|
+
* @returns the transaction hash.
|
|
1257
|
+
*/
|
|
1258
|
+
async submitGovAddNewMarketProposal(
|
|
1259
|
+
wallet: LocalWallet,
|
|
1260
|
+
params: GovAddNewMarketParams,
|
|
1261
|
+
title: string,
|
|
1262
|
+
summary: string,
|
|
1263
|
+
initialDepositAmount: string,
|
|
1264
|
+
memo?: string,
|
|
1265
|
+
metadata?: string,
|
|
1266
|
+
expedited?: boolean,
|
|
1267
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1268
|
+
const msg: Promise<EncodeObject[]> = new Promise((resolve) => {
|
|
1269
|
+
const composer = this.validatorClient.post.composer;
|
|
1270
|
+
const registry = generateRegistry();
|
|
1271
|
+
const msgs: EncodeObject[] = [];
|
|
1272
|
+
|
|
1273
|
+
const isDydxUsd = params.ticker.toLowerCase() === 'dydx-usd';
|
|
1274
|
+
|
|
1275
|
+
// x/prices.MsgCreateOracleMarket
|
|
1276
|
+
const createOracleMarket = composer.composeMsgCreateOracleMarket(
|
|
1277
|
+
params.id,
|
|
1278
|
+
params.ticker,
|
|
1279
|
+
params.priceExponent,
|
|
1280
|
+
params.minExchanges,
|
|
1281
|
+
params.minPriceChange,
|
|
1282
|
+
params.exchangeConfigJson,
|
|
1283
|
+
);
|
|
1284
|
+
|
|
1285
|
+
// x/perpetuals.MsgCreatePerpetual
|
|
1286
|
+
const createPerpetual = composer.composeMsgCreatePerpetual(
|
|
1287
|
+
params.id,
|
|
1288
|
+
isDydxUsd ? 1000001 : params.id,
|
|
1289
|
+
params.ticker,
|
|
1290
|
+
params.atomicResolution,
|
|
1291
|
+
params.liquidityTier,
|
|
1292
|
+
params.marketType,
|
|
1293
|
+
);
|
|
1294
|
+
|
|
1295
|
+
// x/clob.MsgCreateClobPair
|
|
1296
|
+
const createClobPair = composer.composeMsgCreateClobPair(
|
|
1297
|
+
params.id,
|
|
1298
|
+
params.id,
|
|
1299
|
+
params.quantumConversionExponent,
|
|
1300
|
+
params.stepBaseQuantums,
|
|
1301
|
+
params.subticksPerTick,
|
|
1302
|
+
);
|
|
1303
|
+
|
|
1304
|
+
// x/clob.MsgUpdateClobPair
|
|
1305
|
+
const updateClobPair = composer.composeMsgUpdateClobPair(
|
|
1306
|
+
params.id,
|
|
1307
|
+
params.id,
|
|
1308
|
+
params.quantumConversionExponent,
|
|
1309
|
+
params.stepBaseQuantums,
|
|
1310
|
+
params.subticksPerTick,
|
|
1311
|
+
);
|
|
1312
|
+
|
|
1313
|
+
// x/delaymsg.MsgDelayMessage
|
|
1314
|
+
const delayMessage = composer.composeMsgDelayMessage(
|
|
1315
|
+
// IMPORTANT: must wrap messages in Any type to fit into delaymsg.
|
|
1316
|
+
composer.wrapMessageAsAny(registry, updateClobPair),
|
|
1317
|
+
params.delayBlocks,
|
|
1318
|
+
);
|
|
1319
|
+
|
|
1320
|
+
// The order matters.
|
|
1321
|
+
if (!isDydxUsd) {
|
|
1322
|
+
msgs.push(createOracleMarket);
|
|
1323
|
+
}
|
|
1324
|
+
msgs.push(createPerpetual);
|
|
1325
|
+
msgs.push(createClobPair);
|
|
1326
|
+
msgs.push(delayMessage);
|
|
1327
|
+
|
|
1328
|
+
// x/gov.v1.MsgSubmitProposal
|
|
1329
|
+
const submitProposal = composer.composeMsgSubmitProposal(
|
|
1330
|
+
title,
|
|
1331
|
+
initialDepositAmount,
|
|
1332
|
+
this.validatorClient.config.denoms, // use the client denom.
|
|
1333
|
+
summary,
|
|
1334
|
+
// IMPORTANT: must wrap messages in Any type for gov's submit proposal.
|
|
1335
|
+
composer.wrapMessageArrAsAny(registry, msgs),
|
|
1336
|
+
wallet.address!, // proposer
|
|
1337
|
+
metadata,
|
|
1338
|
+
expedited,
|
|
1339
|
+
);
|
|
1340
|
+
|
|
1341
|
+
resolve([submitProposal]);
|
|
1342
|
+
});
|
|
1343
|
+
|
|
1344
|
+
return this.send(SubaccountInfo.forLocalWallet(wallet), () => msg, false, undefined, memo);
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
async createMarketPermissionless(
|
|
1348
|
+
subaccount: SubaccountInfo,
|
|
1349
|
+
ticker: string,
|
|
1350
|
+
broadcastMode?: BroadcastMode,
|
|
1351
|
+
gasAdjustment?: number,
|
|
1352
|
+
memo?: string,
|
|
1353
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1354
|
+
return this.validatorClient.post.createMarketPermissionless(
|
|
1355
|
+
ticker,
|
|
1356
|
+
subaccount,
|
|
1357
|
+
broadcastMode,
|
|
1358
|
+
gasAdjustment,
|
|
1359
|
+
memo,
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
|
|
1363
|
+
async addAuthenticator(
|
|
1364
|
+
subaccount: SubaccountInfo,
|
|
1365
|
+
authenticatorType: AuthenticatorType,
|
|
1366
|
+
data: Uint8Array,
|
|
1367
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1368
|
+
// Validate the provided authenticators before sending to the validator
|
|
1369
|
+
const authenticator: Authenticator = {
|
|
1370
|
+
type: authenticatorType,
|
|
1371
|
+
config: JSON.parse(new TextDecoder().decode(data)),
|
|
1372
|
+
};
|
|
1373
|
+
if (!this.validateAuthenticator(authenticator)) {
|
|
1374
|
+
throw new Error(
|
|
1375
|
+
'Invalid authenticator, please ensure the authenticator permissions are correct',
|
|
1376
|
+
);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
return this.validatorClient.post.addAuthenticator(subaccount, authenticatorType, data);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
async removeAuthenticator(
|
|
1383
|
+
subaccount: SubaccountInfo,
|
|
1384
|
+
id: string,
|
|
1385
|
+
): Promise<BroadcastTxAsyncResponse | BroadcastTxSyncResponse | IndexedTx> {
|
|
1386
|
+
return this.validatorClient.post.removeAuthenticator(subaccount, Long.fromString(id));
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
async getAuthenticators(address: string): Promise<GetAuthenticatorsResponse> {
|
|
1390
|
+
return this.validatorClient.get.getAuthenticators(address);
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
validateAuthenticator(authenticator: Authenticator): boolean {
|
|
1394
|
+
const decodeCompositeConfig = (config: unknown): Authenticator[] | null => {
|
|
1395
|
+
if (Array.isArray(config)) {
|
|
1396
|
+
return config as Authenticator[];
|
|
1397
|
+
}
|
|
1398
|
+
if (typeof config === 'string') {
|
|
1399
|
+
try {
|
|
1400
|
+
const decoded = Buffer.from(config, 'base64').toString('utf8');
|
|
1401
|
+
const parsed = JSON.parse(decoded);
|
|
1402
|
+
return Array.isArray(parsed) ? (parsed as Authenticator[]) : null;
|
|
1403
|
+
} catch {
|
|
1404
|
+
return null;
|
|
1405
|
+
}
|
|
1406
|
+
}
|
|
1407
|
+
return null;
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
const checkAuthenticator = (auth: Authenticator): boolean => {
|
|
1411
|
+
if (auth.type === AuthenticatorType.SIGNATURE_VERIFICATION) {
|
|
1412
|
+
return true;
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
if (auth.type === AuthenticatorType.ANY_OF || auth.type === AuthenticatorType.ALL_OF) {
|
|
1416
|
+
const subAuthenticators = decodeCompositeConfig(auth.config);
|
|
1417
|
+
if (subAuthenticators == null) {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
if (auth.type === AuthenticatorType.ANY_OF) {
|
|
1421
|
+
return subAuthenticators.every((nested) => checkAuthenticator(nested));
|
|
1422
|
+
}
|
|
1423
|
+
return subAuthenticators.some((nested) => checkAuthenticator(nested));
|
|
1424
|
+
}
|
|
1425
|
+
|
|
1426
|
+
return false;
|
|
1427
|
+
};
|
|
1428
|
+
|
|
1429
|
+
return checkAuthenticator(authenticator);
|
|
1430
|
+
}
|
|
1431
|
+
}
|