@upbit-official/upbit-sdk 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +390 -0
- package/api-promise.d.mts +2 -0
- package/api-promise.d.mts.map +1 -0
- package/api-promise.d.ts +2 -0
- package/api-promise.d.ts.map +1 -0
- package/api-promise.js +6 -0
- package/api-promise.js.map +1 -0
- package/api-promise.mjs +2 -0
- package/api-promise.mjs.map +1 -0
- package/client.d.mts +261 -0
- package/client.d.mts.map +1 -0
- package/client.d.ts +261 -0
- package/client.d.ts.map +1 -0
- package/client.js +557 -0
- package/client.js.map +1 -0
- package/client.mjs +553 -0
- package/client.mjs.map +1 -0
- package/core/EventEmitter.d.mts +56 -0
- package/core/EventEmitter.d.mts.map +1 -0
- package/core/EventEmitter.d.ts +56 -0
- package/core/EventEmitter.d.ts.map +1 -0
- package/core/EventEmitter.js +93 -0
- package/core/EventEmitter.js.map +1 -0
- package/core/EventEmitter.mjs +88 -0
- package/core/EventEmitter.mjs.map +1 -0
- package/core/api-promise.d.mts +46 -0
- package/core/api-promise.d.mts.map +1 -0
- package/core/api-promise.d.ts +46 -0
- package/core/api-promise.d.ts.map +1 -0
- package/core/api-promise.js +73 -0
- package/core/api-promise.js.map +1 -0
- package/core/api-promise.mjs +69 -0
- package/core/api-promise.mjs.map +1 -0
- package/core/error.d.mts +51 -0
- package/core/error.d.mts.map +1 -0
- package/core/error.d.ts +51 -0
- package/core/error.d.ts.map +1 -0
- package/core/error.js +150 -0
- package/core/error.js.map +1 -0
- package/core/error.mjs +133 -0
- package/core/error.mjs.map +1 -0
- package/core/pagination.d.mts +63 -0
- package/core/pagination.d.mts.map +1 -0
- package/core/pagination.d.ts +63 -0
- package/core/pagination.d.ts.map +1 -0
- package/core/pagination.js +125 -0
- package/core/pagination.js.map +1 -0
- package/core/pagination.mjs +118 -0
- package/core/pagination.mjs.map +1 -0
- package/core/resource.d.mts +6 -0
- package/core/resource.d.mts.map +1 -0
- package/core/resource.d.ts +6 -0
- package/core/resource.d.ts.map +1 -0
- package/core/resource.js +10 -0
- package/core/resource.js.map +1 -0
- package/core/resource.mjs +6 -0
- package/core/resource.mjs.map +1 -0
- package/core/uploads.d.mts +3 -0
- package/core/uploads.d.mts.map +1 -0
- package/core/uploads.d.ts +3 -0
- package/core/uploads.d.ts.map +1 -0
- package/core/uploads.js +6 -0
- package/core/uploads.js.map +1 -0
- package/core/uploads.mjs +2 -0
- package/core/uploads.mjs.map +1 -0
- package/error.d.mts +2 -0
- package/error.d.mts.map +1 -0
- package/error.d.ts +2 -0
- package/error.d.ts.map +1 -0
- package/error.js +6 -0
- package/error.js.map +1 -0
- package/error.mjs +2 -0
- package/error.mjs.map +1 -0
- package/index.d.mts +8 -0
- package/index.d.mts.map +1 -0
- package/index.d.ts +8 -0
- package/index.d.ts.map +1 -0
- package/index.js +36 -0
- package/index.js.map +1 -0
- package/index.mjs +8 -0
- package/index.mjs.map +1 -0
- package/internal/builtin-types.d.mts +73 -0
- package/internal/builtin-types.d.mts.map +1 -0
- package/internal/builtin-types.d.ts +73 -0
- package/internal/builtin-types.d.ts.map +1 -0
- package/internal/builtin-types.js +3 -0
- package/internal/builtin-types.js.map +1 -0
- package/internal/builtin-types.mjs +2 -0
- package/internal/builtin-types.mjs.map +1 -0
- package/internal/errors.d.mts +3 -0
- package/internal/errors.d.mts.map +1 -0
- package/internal/errors.d.ts +3 -0
- package/internal/errors.d.ts.map +1 -0
- package/internal/errors.js +40 -0
- package/internal/errors.js.map +1 -0
- package/internal/errors.mjs +35 -0
- package/internal/errors.mjs.map +1 -0
- package/internal/headers.d.mts +20 -0
- package/internal/headers.d.mts.map +1 -0
- package/internal/headers.d.ts +20 -0
- package/internal/headers.d.ts.map +1 -0
- package/internal/headers.js +78 -0
- package/internal/headers.js.map +1 -0
- package/internal/headers.mjs +73 -0
- package/internal/headers.mjs.map +1 -0
- package/internal/parse.d.mts +12 -0
- package/internal/parse.d.mts.map +1 -0
- package/internal/parse.d.ts +12 -0
- package/internal/parse.d.ts.map +1 -0
- package/internal/parse.js +40 -0
- package/internal/parse.js.map +1 -0
- package/internal/parse.mjs +37 -0
- package/internal/parse.mjs.map +1 -0
- package/internal/qs/formats.d.mts +7 -0
- package/internal/qs/formats.d.mts.map +1 -0
- package/internal/qs/formats.d.ts +7 -0
- package/internal/qs/formats.d.ts.map +1 -0
- package/internal/qs/formats.js +13 -0
- package/internal/qs/formats.js.map +1 -0
- package/internal/qs/formats.mjs +9 -0
- package/internal/qs/formats.mjs.map +1 -0
- package/internal/qs/index.d.mts +10 -0
- package/internal/qs/index.d.mts.map +1 -0
- package/internal/qs/index.d.ts +10 -0
- package/internal/qs/index.d.ts.map +1 -0
- package/internal/qs/index.js +14 -0
- package/internal/qs/index.js.map +1 -0
- package/internal/qs/index.mjs +10 -0
- package/internal/qs/index.mjs.map +1 -0
- package/internal/qs/stringify.d.mts +3 -0
- package/internal/qs/stringify.d.mts.map +1 -0
- package/internal/qs/stringify.d.ts +3 -0
- package/internal/qs/stringify.d.ts.map +1 -0
- package/internal/qs/stringify.js +277 -0
- package/internal/qs/stringify.js.map +1 -0
- package/internal/qs/stringify.mjs +274 -0
- package/internal/qs/stringify.mjs.map +1 -0
- package/internal/qs/types.d.mts +57 -0
- package/internal/qs/types.d.mts.map +1 -0
- package/internal/qs/types.d.ts +57 -0
- package/internal/qs/types.d.ts.map +1 -0
- package/internal/qs/types.js +3 -0
- package/internal/qs/types.js.map +1 -0
- package/internal/qs/types.mjs +2 -0
- package/internal/qs/types.mjs.map +1 -0
- package/internal/qs/utils.d.mts +15 -0
- package/internal/qs/utils.d.mts.map +1 -0
- package/internal/qs/utils.d.ts +15 -0
- package/internal/qs/utils.d.ts.map +1 -0
- package/internal/qs/utils.js +230 -0
- package/internal/qs/utils.js.map +1 -0
- package/internal/qs/utils.mjs +217 -0
- package/internal/qs/utils.mjs.map +1 -0
- package/internal/request-options.d.mts +78 -0
- package/internal/request-options.d.mts.map +1 -0
- package/internal/request-options.d.ts +78 -0
- package/internal/request-options.d.ts.map +1 -0
- package/internal/request-options.js +13 -0
- package/internal/request-options.js.map +1 -0
- package/internal/request-options.mjs +9 -0
- package/internal/request-options.mjs.map +1 -0
- package/internal/shim-types.d.mts +17 -0
- package/internal/shim-types.d.mts.map +1 -0
- package/internal/shim-types.d.ts +17 -0
- package/internal/shim-types.d.ts.map +1 -0
- package/internal/shim-types.js +9 -0
- package/internal/shim-types.js.map +1 -0
- package/internal/shim-types.mjs +8 -0
- package/internal/shim-types.mjs.map +1 -0
- package/internal/shims.d.mts +26 -0
- package/internal/shims.d.mts.map +1 -0
- package/internal/shims.d.ts +26 -0
- package/internal/shims.d.ts.map +1 -0
- package/internal/shims.js +97 -0
- package/internal/shims.js.map +1 -0
- package/internal/shims.mjs +90 -0
- package/internal/shims.mjs.map +1 -0
- package/internal/to-file.d.mts +45 -0
- package/internal/to-file.d.mts.map +1 -0
- package/internal/to-file.d.ts +45 -0
- package/internal/to-file.d.ts.map +1 -0
- package/internal/to-file.js +91 -0
- package/internal/to-file.js.map +1 -0
- package/internal/to-file.mjs +88 -0
- package/internal/to-file.mjs.map +1 -0
- package/internal/tslib.js +81 -0
- package/internal/tslib.mjs +17 -0
- package/internal/types.d.mts +69 -0
- package/internal/types.d.mts.map +1 -0
- package/internal/types.d.ts +69 -0
- package/internal/types.d.ts.map +1 -0
- package/internal/types.js +3 -0
- package/internal/types.js.map +1 -0
- package/internal/types.mjs +2 -0
- package/internal/types.mjs.map +1 -0
- package/internal/uploads.d.mts +42 -0
- package/internal/uploads.d.mts.map +1 -0
- package/internal/uploads.d.ts +42 -0
- package/internal/uploads.d.ts.map +1 -0
- package/internal/uploads.js +141 -0
- package/internal/uploads.js.map +1 -0
- package/internal/uploads.mjs +131 -0
- package/internal/uploads.mjs.map +1 -0
- package/internal/utils/base64.d.mts +3 -0
- package/internal/utils/base64.d.mts.map +1 -0
- package/internal/utils/base64.d.ts +3 -0
- package/internal/utils/base64.d.ts.map +1 -0
- package/internal/utils/base64.js +37 -0
- package/internal/utils/base64.js.map +1 -0
- package/internal/utils/base64.mjs +32 -0
- package/internal/utils/base64.mjs.map +1 -0
- package/internal/utils/bytes.d.mts +4 -0
- package/internal/utils/bytes.d.mts.map +1 -0
- package/internal/utils/bytes.d.ts +4 -0
- package/internal/utils/bytes.d.ts.map +1 -0
- package/internal/utils/bytes.js +31 -0
- package/internal/utils/bytes.js.map +1 -0
- package/internal/utils/bytes.mjs +26 -0
- package/internal/utils/bytes.mjs.map +1 -0
- package/internal/utils/env.d.mts +9 -0
- package/internal/utils/env.d.mts.map +1 -0
- package/internal/utils/env.d.ts +9 -0
- package/internal/utils/env.d.ts.map +1 -0
- package/internal/utils/env.js +21 -0
- package/internal/utils/env.js.map +1 -0
- package/internal/utils/env.mjs +17 -0
- package/internal/utils/env.mjs.map +1 -0
- package/internal/utils/log.d.mts +37 -0
- package/internal/utils/log.d.mts.map +1 -0
- package/internal/utils/log.d.ts +37 -0
- package/internal/utils/log.d.ts.map +1 -0
- package/internal/utils/log.js +84 -0
- package/internal/utils/log.js.map +1 -0
- package/internal/utils/log.mjs +78 -0
- package/internal/utils/log.mjs.map +1 -0
- package/internal/utils/path.d.mts +15 -0
- package/internal/utils/path.d.mts.map +1 -0
- package/internal/utils/path.d.ts +15 -0
- package/internal/utils/path.d.ts.map +1 -0
- package/internal/utils/path.js +79 -0
- package/internal/utils/path.js.map +1 -0
- package/internal/utils/path.mjs +74 -0
- package/internal/utils/path.mjs.map +1 -0
- package/internal/utils/query.d.mts +2 -0
- package/internal/utils/query.d.mts.map +1 -0
- package/internal/utils/query.d.ts +2 -0
- package/internal/utils/query.d.ts.map +1 -0
- package/internal/utils/query.js +9 -0
- package/internal/utils/query.js.map +1 -0
- package/internal/utils/query.mjs +5 -0
- package/internal/utils/query.mjs.map +1 -0
- package/internal/utils/sleep.d.mts +2 -0
- package/internal/utils/sleep.d.mts.map +1 -0
- package/internal/utils/sleep.d.ts +2 -0
- package/internal/utils/sleep.d.ts.map +1 -0
- package/internal/utils/sleep.js +6 -0
- package/internal/utils/sleep.js.map +1 -0
- package/internal/utils/sleep.mjs +2 -0
- package/internal/utils/sleep.mjs.map +1 -0
- package/internal/utils/uuid.d.mts +5 -0
- package/internal/utils/uuid.d.mts.map +1 -0
- package/internal/utils/uuid.d.ts +5 -0
- package/internal/utils/uuid.d.ts.map +1 -0
- package/internal/utils/uuid.js +21 -0
- package/internal/utils/uuid.js.map +1 -0
- package/internal/utils/uuid.mjs +17 -0
- package/internal/utils/uuid.mjs.map +1 -0
- package/internal/utils/values.d.mts +18 -0
- package/internal/utils/values.d.mts.map +1 -0
- package/internal/utils/values.d.ts +18 -0
- package/internal/utils/values.d.ts.map +1 -0
- package/internal/utils/values.js +111 -0
- package/internal/utils/values.js.map +1 -0
- package/internal/utils/values.mjs +93 -0
- package/internal/utils/values.mjs.map +1 -0
- package/internal/utils.d.mts +8 -0
- package/internal/utils.d.mts.map +1 -0
- package/internal/utils.d.ts +8 -0
- package/internal/utils.d.ts.map +1 -0
- package/internal/utils.js +11 -0
- package/internal/utils.js.map +1 -0
- package/internal/utils.mjs +8 -0
- package/internal/utils.mjs.map +1 -0
- package/internal/ws.d.mts +31 -0
- package/internal/ws.d.mts.map +1 -0
- package/internal/ws.d.ts +31 -0
- package/internal/ws.d.ts.map +1 -0
- package/internal/ws.js +39 -0
- package/internal/ws.js.map +1 -0
- package/internal/ws.mjs +36 -0
- package/internal/ws.mjs.map +1 -0
- package/lib/index.d.mts +5 -0
- package/lib/index.d.mts.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +11 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +4 -0
- package/lib/index.mjs.map +1 -0
- package/lib/jsonParseFloat.d.mts +16 -0
- package/lib/jsonParseFloat.d.mts.map +1 -0
- package/lib/jsonParseFloat.d.ts +16 -0
- package/lib/jsonParseFloat.d.ts.map +1 -0
- package/lib/jsonParseFloat.js +77 -0
- package/lib/jsonParseFloat.js.map +1 -0
- package/lib/jsonParseFloat.mjs +74 -0
- package/lib/jsonParseFloat.mjs.map +1 -0
- package/lib/jwtAuth.d.mts +7 -0
- package/lib/jwtAuth.d.mts.map +1 -0
- package/lib/jwtAuth.d.ts +7 -0
- package/lib/jwtAuth.d.ts.map +1 -0
- package/lib/jwtAuth.js +33 -0
- package/lib/jwtAuth.js.map +1 -0
- package/lib/jwtAuth.mjs +30 -0
- package/lib/jwtAuth.mjs.map +1 -0
- package/lib/ws.d.mts +95 -0
- package/lib/ws.d.mts.map +1 -0
- package/lib/ws.d.ts +95 -0
- package/lib/ws.d.ts.map +1 -0
- package/lib/ws.js +229 -0
- package/lib/ws.js.map +1 -0
- package/lib/ws.mjs +223 -0
- package/lib/ws.mjs.map +1 -0
- package/package.json +169 -0
- package/pagination.d.mts +2 -0
- package/pagination.d.mts.map +1 -0
- package/pagination.d.ts +2 -0
- package/pagination.d.ts.map +1 -0
- package/pagination.js +6 -0
- package/pagination.js.map +1 -0
- package/pagination.mjs +2 -0
- package/pagination.mjs.map +1 -0
- package/resource.d.mts +2 -0
- package/resource.d.mts.map +1 -0
- package/resource.d.ts +2 -0
- package/resource.d.ts.map +1 -0
- package/resource.js +6 -0
- package/resource.js.map +1 -0
- package/resource.mjs +2 -0
- package/resource.mjs.map +1 -0
- package/resources/accounts.d.mts +48 -0
- package/resources/accounts.d.mts.map +1 -0
- package/resources/accounts.d.ts +48 -0
- package/resources/accounts.d.ts.map +1 -0
- package/resources/accounts.js +19 -0
- package/resources/accounts.js.map +1 -0
- package/resources/accounts.mjs +15 -0
- package/resources/accounts.mjs.map +1 -0
- package/resources/api-keys.d.mts +33 -0
- package/resources/api-keys.d.mts.map +1 -0
- package/resources/api-keys.d.ts +33 -0
- package/resources/api-keys.d.ts.map +1 -0
- package/resources/api-keys.js +19 -0
- package/resources/api-keys.js.map +1 -0
- package/resources/api-keys.mjs +15 -0
- package/resources/api-keys.mjs.map +1 -0
- package/resources/candles.d.mts +310 -0
- package/resources/candles.d.mts.map +1 -0
- package/resources/candles.d.ts +310 -0
- package/resources/candles.d.ts.map +1 -0
- package/resources/candles.js +117 -0
- package/resources/candles.js.map +1 -0
- package/resources/candles.mjs +113 -0
- package/resources/candles.mjs.map +1 -0
- package/resources/deposits.d.mts +373 -0
- package/resources/deposits.d.mts.map +1 -0
- package/resources/deposits.d.ts +373 -0
- package/resources/deposits.d.ts.map +1 -0
- package/resources/deposits.js +139 -0
- package/resources/deposits.js.map +1 -0
- package/resources/deposits.mjs +135 -0
- package/resources/deposits.mjs.map +1 -0
- package/resources/index.d.mts +15 -0
- package/resources/index.d.mts.map +1 -0
- package/resources/index.d.ts +15 -0
- package/resources/index.d.ts.map +1 -0
- package/resources/index.js +32 -0
- package/resources/index.js.map +1 -0
- package/resources/index.mjs +15 -0
- package/resources/index.mjs.map +1 -0
- package/resources/orderbooks.d.mts +134 -0
- package/resources/orderbooks.d.mts.map +1 -0
- package/resources/orderbooks.d.ts +134 -0
- package/resources/orderbooks.d.ts.map +1 -0
- package/resources/orderbooks.js +31 -0
- package/resources/orderbooks.js.map +1 -0
- package/resources/orderbooks.mjs +27 -0
- package/resources/orderbooks.mjs.map +1 -0
- package/resources/orders.d.mts +886 -0
- package/resources/orders.d.mts.map +1 -0
- package/resources/orders.d.ts +886 -0
- package/resources/orders.d.ts.map +1 -0
- package/resources/orders.js +250 -0
- package/resources/orders.js.map +1 -0
- package/resources/orders.mjs +246 -0
- package/resources/orders.mjs.map +1 -0
- package/resources/tickers.d.mts +184 -0
- package/resources/tickers.d.mts.map +1 -0
- package/resources/tickers.d.ts +184 -0
- package/resources/tickers.d.ts.map +1 -0
- package/resources/tickers.js +30 -0
- package/resources/tickers.js.map +1 -0
- package/resources/tickers.mjs +26 -0
- package/resources/tickers.mjs.map +1 -0
- package/resources/trades.d.mts +107 -0
- package/resources/trades.d.mts.map +1 -0
- package/resources/trades.d.ts +107 -0
- package/resources/trades.d.ts.map +1 -0
- package/resources/trades.js +19 -0
- package/resources/trades.js.map +1 -0
- package/resources/trades.mjs +15 -0
- package/resources/trades.mjs.map +1 -0
- package/resources/trading-pairs.d.mts +96 -0
- package/resources/trading-pairs.d.mts.map +1 -0
- package/resources/trading-pairs.d.ts +96 -0
- package/resources/trading-pairs.d.ts.map +1 -0
- package/resources/trading-pairs.js +19 -0
- package/resources/trading-pairs.js.map +1 -0
- package/resources/trading-pairs.mjs +15 -0
- package/resources/trading-pairs.mjs.map +1 -0
- package/resources/travel-rule.d.mts +139 -0
- package/resources/travel-rule.d.mts.map +1 -0
- package/resources/travel-rule.d.ts +139 -0
- package/resources/travel-rule.d.ts.map +1 -0
- package/resources/travel-rule.js +68 -0
- package/resources/travel-rule.js.map +1 -0
- package/resources/travel-rule.mjs +64 -0
- package/resources/travel-rule.mjs.map +1 -0
- package/resources/wallet-status.d.mts +74 -0
- package/resources/wallet-status.d.mts.map +1 -0
- package/resources/wallet-status.d.ts +74 -0
- package/resources/wallet-status.d.ts.map +1 -0
- package/resources/wallet-status.js +19 -0
- package/resources/wallet-status.js.map +1 -0
- package/resources/wallet-status.mjs +15 -0
- package/resources/wallet-status.mjs.map +1 -0
- package/resources/withdraws.d.mts +599 -0
- package/resources/withdraws.d.mts.map +1 -0
- package/resources/withdraws.d.ts +599 -0
- package/resources/withdraws.d.ts.map +1 -0
- package/resources/withdraws.js +139 -0
- package/resources/withdraws.js.map +1 -0
- package/resources/withdraws.mjs +135 -0
- package/resources/withdraws.mjs.map +1 -0
- package/resources/ws-private/index.d.mts +3 -0
- package/resources/ws-private/index.d.mts.map +1 -0
- package/resources/ws-private/index.d.ts +3 -0
- package/resources/ws-private/index.d.ts.map +1 -0
- package/resources/ws-private/index.js +6 -0
- package/resources/ws-private/index.js.map +1 -0
- package/resources/ws-private/index.mjs +2 -0
- package/resources/ws-private/index.mjs.map +1 -0
- package/resources/ws-private/internal-base.d.mts +58 -0
- package/resources/ws-private/internal-base.d.mts.map +1 -0
- package/resources/ws-private/internal-base.d.ts +58 -0
- package/resources/ws-private/internal-base.d.ts.map +1 -0
- package/resources/ws-private/internal-base.js +51 -0
- package/resources/ws-private/internal-base.js.map +1 -0
- package/resources/ws-private/internal-base.mjs +45 -0
- package/resources/ws-private/internal-base.mjs.map +1 -0
- package/resources/ws-private/ws-private.d.mts +224 -0
- package/resources/ws-private/ws-private.d.mts.map +1 -0
- package/resources/ws-private/ws-private.d.ts +224 -0
- package/resources/ws-private/ws-private.d.ts.map +1 -0
- package/resources/ws-private/ws-private.js +8 -0
- package/resources/ws-private/ws-private.js.map +1 -0
- package/resources/ws-private/ws-private.mjs +4 -0
- package/resources/ws-private/ws-private.mjs.map +1 -0
- package/resources/ws-private/ws.d.mts +85 -0
- package/resources/ws-private/ws.d.mts.map +1 -0
- package/resources/ws-private/ws.d.ts +85 -0
- package/resources/ws-private/ws.d.ts.map +1 -0
- package/resources/ws-private/ws.js +433 -0
- package/resources/ws-private/ws.js.map +1 -0
- package/resources/ws-private/ws.mjs +428 -0
- package/resources/ws-private/ws.mjs.map +1 -0
- package/resources/ws-private.d.mts +2 -0
- package/resources/ws-private.d.mts.map +1 -0
- package/resources/ws-private.d.ts +2 -0
- package/resources/ws-private.d.ts.map +1 -0
- package/resources/ws-private.js +5 -0
- package/resources/ws-private.js.map +1 -0
- package/resources/ws-private.mjs +2 -0
- package/resources/ws-private.mjs.map +1 -0
- package/resources/ws-public/index.d.mts +3 -0
- package/resources/ws-public/index.d.mts.map +1 -0
- package/resources/ws-public/index.d.ts +3 -0
- package/resources/ws-public/index.d.ts.map +1 -0
- package/resources/ws-public/index.js +6 -0
- package/resources/ws-public/index.js.map +1 -0
- package/resources/ws-public/index.mjs +2 -0
- package/resources/ws-public/index.mjs.map +1 -0
- package/resources/ws-public/internal-base.d.mts +58 -0
- package/resources/ws-public/internal-base.d.mts.map +1 -0
- package/resources/ws-public/internal-base.d.ts +58 -0
- package/resources/ws-public/internal-base.d.ts.map +1 -0
- package/resources/ws-public/internal-base.js +51 -0
- package/resources/ws-public/internal-base.js.map +1 -0
- package/resources/ws-public/internal-base.mjs +45 -0
- package/resources/ws-public/internal-base.mjs.map +1 -0
- package/resources/ws-public/ws-public.d.mts +427 -0
- package/resources/ws-public/ws-public.d.mts.map +1 -0
- package/resources/ws-public/ws-public.d.ts +427 -0
- package/resources/ws-public/ws-public.d.ts.map +1 -0
- package/resources/ws-public/ws-public.js +8 -0
- package/resources/ws-public/ws-public.js.map +1 -0
- package/resources/ws-public/ws-public.mjs +4 -0
- package/resources/ws-public/ws-public.mjs.map +1 -0
- package/resources/ws-public/ws.d.mts +85 -0
- package/resources/ws-public/ws.d.mts.map +1 -0
- package/resources/ws-public/ws.d.ts +85 -0
- package/resources/ws-public/ws.d.ts.map +1 -0
- package/resources/ws-public/ws.js +428 -0
- package/resources/ws-public/ws.js.map +1 -0
- package/resources/ws-public/ws.mjs +423 -0
- package/resources/ws-public/ws.mjs.map +1 -0
- package/resources/ws-public.d.mts +2 -0
- package/resources/ws-public.d.mts.map +1 -0
- package/resources/ws-public.d.ts +2 -0
- package/resources/ws-public.d.ts.map +1 -0
- package/resources/ws-public.js +5 -0
- package/resources/ws-public.js.map +1 -0
- package/resources/ws-public.mjs +2 -0
- package/resources/ws-public.mjs.map +1 -0
- package/resources.d.mts +2 -0
- package/resources.d.mts.map +1 -0
- package/resources.d.ts +2 -0
- package/resources.d.ts.map +1 -0
- package/resources.js +5 -0
- package/resources.js.map +1 -0
- package/resources.mjs +2 -0
- package/resources.mjs.map +1 -0
- package/src/api-promise.ts +2 -0
- package/src/client.ts +1112 -0
- package/src/core/EventEmitter.ts +114 -0
- package/src/core/README.md +3 -0
- package/src/core/api-promise.ts +91 -0
- package/src/core/error.ts +182 -0
- package/src/core/pagination.ts +195 -0
- package/src/core/resource.ts +10 -0
- package/src/core/uploads.ts +2 -0
- package/src/error.ts +2 -0
- package/src/index.ts +24 -0
- package/src/internal/README.md +3 -0
- package/src/internal/builtin-types.ts +92 -0
- package/src/internal/errors.ts +32 -0
- package/src/internal/headers.ts +96 -0
- package/src/internal/parse.ts +56 -0
- package/src/internal/qs/LICENSE.md +13 -0
- package/src/internal/qs/README.md +3 -0
- package/src/internal/qs/formats.ts +10 -0
- package/src/internal/qs/index.ts +13 -0
- package/src/internal/qs/stringify.ts +385 -0
- package/src/internal/qs/types.ts +71 -0
- package/src/internal/qs/utils.ts +265 -0
- package/src/internal/request-options.ts +92 -0
- package/src/internal/shim-types.ts +25 -0
- package/src/internal/shims.ts +106 -0
- package/src/internal/to-file.ts +154 -0
- package/src/internal/types.ts +94 -0
- package/src/internal/uploads.ts +187 -0
- package/src/internal/utils/base64.ts +39 -0
- package/src/internal/utils/bytes.ts +32 -0
- package/src/internal/utils/env.ts +17 -0
- package/src/internal/utils/log.ts +125 -0
- package/src/internal/utils/path.ts +88 -0
- package/src/internal/utils/query.ts +6 -0
- package/src/internal/utils/sleep.ts +2 -0
- package/src/internal/utils/uuid.ts +19 -0
- package/src/internal/utils/values.ts +104 -0
- package/src/internal/utils.ts +8 -0
- package/src/internal/ws.ts +68 -0
- package/src/lib/index.ts +4 -0
- package/src/lib/jsonParseFloat.ts +73 -0
- package/src/lib/jwtAuth.ts +39 -0
- package/src/lib/ws.ts +282 -0
- package/src/pagination.ts +2 -0
- package/src/resource.ts +2 -0
- package/src/resources/accounts.ts +59 -0
- package/src/resources/api-keys.ts +40 -0
- package/src/resources/candles.ts +392 -0
- package/src/resources/deposits.ts +484 -0
- package/src/resources/index.ts +102 -0
- package/src/resources/orderbooks.ts +170 -0
- package/src/resources/orders.ts +1102 -0
- package/src/resources/tickers.ts +233 -0
- package/src/resources/trades.ts +127 -0
- package/src/resources/trading-pairs.ts +120 -0
- package/src/resources/travel-rule.ts +181 -0
- package/src/resources/wallet-status.ts +87 -0
- package/src/resources/withdraws.ts +734 -0
- package/src/resources/ws-private/index.ts +3 -0
- package/src/resources/ws-private/internal-base.ts +99 -0
- package/src/resources/ws-private/ws-private.ts +283 -0
- package/src/resources/ws-private/ws.ts +529 -0
- package/src/resources/ws-private.ts +2 -0
- package/src/resources/ws-public/index.ts +3 -0
- package/src/resources/ws-public/internal-base.ts +99 -0
- package/src/resources/ws-public/ws-public.ts +561 -0
- package/src/resources/ws-public/ws.ts +525 -0
- package/src/resources/ws-public.ts +2 -0
- package/src/resources.ts +1 -0
- package/src/tsconfig.json +11 -0
- package/src/uploads.ts +2 -0
- package/src/version.ts +1 -0
- package/uploads.d.mts +2 -0
- package/uploads.d.mts.map +1 -0
- package/uploads.d.ts +2 -0
- package/uploads.d.ts.map +1 -0
- package/uploads.js +6 -0
- package/uploads.js.map +1 -0
- package/uploads.mjs +2 -0
- package/uploads.mjs.map +1 -0
- package/version.d.mts +2 -0
- package/version.d.mts.map +1 -0
- package/version.d.ts +2 -0
- package/version.d.ts.map +1 -0
- package/version.js +5 -0
- package/version.js.map +1 -0
- package/version.mjs +2 -0
- package/version.mjs.map +1 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
|
|
2
|
+
import { UpbitError } from '../../core/error';
|
|
3
|
+
|
|
4
|
+
// https://url.spec.whatwg.org/#url-scheme-string
|
|
5
|
+
const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
|
|
6
|
+
|
|
7
|
+
export const isAbsoluteURL = (url: string): boolean => {
|
|
8
|
+
return startsWithSchemeRegexp.test(url);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export let isArray = (val: unknown): val is unknown[] => ((isArray = Array.isArray), isArray(val));
|
|
12
|
+
export let isReadonlyArray = isArray as (val: unknown) => val is readonly unknown[];
|
|
13
|
+
|
|
14
|
+
/** Returns an object if the given value isn't an object, otherwise returns as-is */
|
|
15
|
+
export function maybeObj(x: unknown): object {
|
|
16
|
+
if (typeof x !== 'object') {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return x ?? {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// https://stackoverflow.com/a/34491287
|
|
24
|
+
export function isEmptyObj(obj: Object | null | undefined): boolean {
|
|
25
|
+
if (!obj) return true;
|
|
26
|
+
for (const _k in obj) return false;
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// https://eslint.org/docs/latest/rules/no-prototype-builtins
|
|
31
|
+
export function hasOwn<T extends object = object>(obj: T, key: PropertyKey): key is keyof T {
|
|
32
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isObj(obj: unknown): obj is Record<string, unknown> {
|
|
36
|
+
return obj != null && typeof obj === 'object' && !Array.isArray(obj);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const ensurePresent = <T>(value: T | null | undefined): T => {
|
|
40
|
+
if (value == null) {
|
|
41
|
+
throw new UpbitError(`Expected a value to be given but received ${value} instead.`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return value;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const validatePositiveInteger = (name: string, n: unknown): number => {
|
|
48
|
+
if (typeof n !== 'number' || !Number.isInteger(n)) {
|
|
49
|
+
throw new UpbitError(`${name} must be an integer`);
|
|
50
|
+
}
|
|
51
|
+
if (n < 0) {
|
|
52
|
+
throw new UpbitError(`${name} must be a positive integer`);
|
|
53
|
+
}
|
|
54
|
+
return n;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export const coerceInteger = (value: unknown): number => {
|
|
58
|
+
if (typeof value === 'number') return Math.round(value);
|
|
59
|
+
if (typeof value === 'string') return parseInt(value, 10);
|
|
60
|
+
|
|
61
|
+
throw new UpbitError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export const coerceFloat = (value: unknown): number => {
|
|
65
|
+
if (typeof value === 'number') return value;
|
|
66
|
+
if (typeof value === 'string') return parseFloat(value);
|
|
67
|
+
|
|
68
|
+
throw new UpbitError(`Could not coerce ${value} (type: ${typeof value}) into a number`);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const coerceBoolean = (value: unknown): boolean => {
|
|
72
|
+
if (typeof value === 'boolean') return value;
|
|
73
|
+
if (typeof value === 'string') return value === 'true';
|
|
74
|
+
return Boolean(value);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export const maybeCoerceInteger = (value: unknown): number | undefined => {
|
|
78
|
+
if (value == null) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return coerceInteger(value);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const maybeCoerceFloat = (value: unknown): number | undefined => {
|
|
85
|
+
if (value == null) {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
return coerceFloat(value);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const maybeCoerceBoolean = (value: unknown): boolean | undefined => {
|
|
92
|
+
if (value == null) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return coerceBoolean(value);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const safeJSON = (text: string) => {
|
|
99
|
+
try {
|
|
100
|
+
return JSON.parse(text);
|
|
101
|
+
} catch (err) {
|
|
102
|
+
return undefined;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Reconnection event passed to the `onReconnecting` handler and event listeners. */
|
|
2
|
+
export interface ReconnectingEvent<Parameters = Record<string, unknown>> {
|
|
3
|
+
/** Which retry attempt this is (1-based). */
|
|
4
|
+
readonly attempt: number;
|
|
5
|
+
/** Total attempts that will be made. */
|
|
6
|
+
readonly maxAttempts: number;
|
|
7
|
+
/** Delay in ms before this attempt connects. */
|
|
8
|
+
readonly delay: number;
|
|
9
|
+
/** The WebSocket close code that triggered reconnection. */
|
|
10
|
+
readonly closeCode: number;
|
|
11
|
+
/** The current query parameters. */
|
|
12
|
+
readonly parameters: (Parameters & Record<string, unknown>) | undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Optional overrides returned from the `onReconnecting` handler
|
|
17
|
+
* to customize the next reconnection attempt.
|
|
18
|
+
*/
|
|
19
|
+
export type ReconnectingOverrides<Parameters = Record<string, unknown>> =
|
|
20
|
+
| {
|
|
21
|
+
/**
|
|
22
|
+
* If provided, assigns the query parameters for the next connection.
|
|
23
|
+
* Set to `undefined` to clear all query parameters.
|
|
24
|
+
*/
|
|
25
|
+
parameters?: (Parameters & Record<string, unknown>) | undefined;
|
|
26
|
+
}
|
|
27
|
+
| {
|
|
28
|
+
/**
|
|
29
|
+
* If set, will stop attempting to reconnect.
|
|
30
|
+
*/
|
|
31
|
+
abort: true;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// RFC 6455 §7.4.1
|
|
35
|
+
export function isRecoverableClose(code: number): boolean {
|
|
36
|
+
switch (code) {
|
|
37
|
+
case 1000:
|
|
38
|
+
return false; // Normal closure
|
|
39
|
+
case 1001:
|
|
40
|
+
return true; // Going away (server shutting down)
|
|
41
|
+
case 1002:
|
|
42
|
+
return false; // Protocol error
|
|
43
|
+
case 1003:
|
|
44
|
+
return false; // Unsupported data
|
|
45
|
+
case 1005:
|
|
46
|
+
return true; // No status code (abnormal)
|
|
47
|
+
case 1006:
|
|
48
|
+
return true; // Abnormal closure (network drop)
|
|
49
|
+
case 1007:
|
|
50
|
+
return false; // Invalid payload
|
|
51
|
+
case 1008:
|
|
52
|
+
return false; // Policy violation
|
|
53
|
+
case 1009:
|
|
54
|
+
return false; // Message too big
|
|
55
|
+
case 1010:
|
|
56
|
+
return false; // Missing extension
|
|
57
|
+
case 1011:
|
|
58
|
+
return true; // Internal server error
|
|
59
|
+
case 1012:
|
|
60
|
+
return true; // Service restart
|
|
61
|
+
case 1013:
|
|
62
|
+
return true; // Try again later
|
|
63
|
+
case 1015:
|
|
64
|
+
return true; // TLS handshake failure
|
|
65
|
+
default:
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fields declared as `number` in the SDK response interfaces.
|
|
3
|
+
* All other fields with `typeof value === 'number'` at runtime
|
|
4
|
+
* are assumed to be `string`-typed and will be coerced to strings.
|
|
5
|
+
*/
|
|
6
|
+
const NUMBER_FIELDS: Set<string> = new Set([
|
|
7
|
+
'timestamp',
|
|
8
|
+
'trade_timestamp',
|
|
9
|
+
'sequential_id',
|
|
10
|
+
'trades_count',
|
|
11
|
+
'count',
|
|
12
|
+
'decimal_precision',
|
|
13
|
+
'minimum_deposit_confirmations',
|
|
14
|
+
'block_elapsed_minutes',
|
|
15
|
+
'fee_level',
|
|
16
|
+
'security_level',
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Parses a JSON string with type-aware coercion.
|
|
21
|
+
*
|
|
22
|
+
* 1st pass (JSON.parse reviver): float tokens (containing `.`, `e`, `E`) are
|
|
23
|
+
* preserved as their original string representation to avoid precision loss.
|
|
24
|
+
* Uses the reviver's third argument `context.source` (TypeScript 5.2+ / modern runtimes).
|
|
25
|
+
* Falls back to standard number parsing when `context.source` is unavailable.
|
|
26
|
+
*
|
|
27
|
+
* 2nd pass (constructType): coerces values to match SDK declared types.
|
|
28
|
+
* - `string`-declared fields: `number` → `string` (e.g. balance `0` → `"0"`)
|
|
29
|
+
* - `number`-declared fields: `string` → `number` (e.g. timestamp `"123.45"` → `123.45`)
|
|
30
|
+
*
|
|
31
|
+
* Mirrors the behavior of Python SDK's `json.loads(parse_float=str)` + `construct_type()`.
|
|
32
|
+
*/
|
|
33
|
+
export function jsonParseFloat(text: string): unknown {
|
|
34
|
+
const parsed = JSON.parse(text, (key: string, value: unknown, context?: { source?: string }) => {
|
|
35
|
+
if (typeof value !== 'number') return value;
|
|
36
|
+
const src = context?.source;
|
|
37
|
+
if (!src) return value;
|
|
38
|
+
return /[.eE]/.test(src) ? src : value;
|
|
39
|
+
});
|
|
40
|
+
return constructType(parsed);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function constructType(data: unknown): unknown {
|
|
44
|
+
if (Array.isArray(data)) {
|
|
45
|
+
return data.map(constructType);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (data !== null && typeof data === 'object') {
|
|
49
|
+
const obj = data as Record<string, unknown>;
|
|
50
|
+
const result: Record<string, unknown> = {};
|
|
51
|
+
for (const key of Object.keys(obj)) {
|
|
52
|
+
const value = obj[key];
|
|
53
|
+
|
|
54
|
+
if (NUMBER_FIELDS.has(key)) {
|
|
55
|
+
// number-declared field: coerce string → number
|
|
56
|
+
if (typeof value === 'string') {
|
|
57
|
+
result[key] = Number(value);
|
|
58
|
+
} else {
|
|
59
|
+
result[key] = value;
|
|
60
|
+
}
|
|
61
|
+
} else if (typeof value === 'number') {
|
|
62
|
+
// string-declared field: coerce number → string
|
|
63
|
+
result[key] = String(value);
|
|
64
|
+
} else {
|
|
65
|
+
// recurse into nested objects and arrays
|
|
66
|
+
result[key] = constructType(value);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return data;
|
|
73
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createHmac, createHash } from 'crypto';
|
|
2
|
+
import { uuid4 } from '../internal/utils/uuid';
|
|
3
|
+
import { stringifyQuery } from '../internal/utils/query';
|
|
4
|
+
|
|
5
|
+
function base64url(buf: Buffer): string {
|
|
6
|
+
return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Creates a JWT token for Upbit API authentication (HS256).
|
|
11
|
+
*
|
|
12
|
+
* If query parameters are provided, their SHA512 hash is included in the payload.
|
|
13
|
+
*/
|
|
14
|
+
export function createJwtToken(
|
|
15
|
+
accessKey: string,
|
|
16
|
+
secretKey: string,
|
|
17
|
+
queryParams?: Record<string, unknown> | null,
|
|
18
|
+
): string {
|
|
19
|
+
const header = { alg: 'HS256', typ: 'JWT' };
|
|
20
|
+
|
|
21
|
+
const payload: Record<string, unknown> = {
|
|
22
|
+
access_key: accessKey,
|
|
23
|
+
nonce: uuid4(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (queryParams && Object.keys(queryParams).length > 0) {
|
|
27
|
+
const queryString = decodeURIComponent(stringifyQuery(queryParams));
|
|
28
|
+
const queryHash = createHash('sha512').update(queryString, 'utf8').digest('hex');
|
|
29
|
+
payload['query_hash'] = queryHash;
|
|
30
|
+
payload['query_hash_alg'] = 'SHA512';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const encodedHeader = base64url(Buffer.from(JSON.stringify(header)));
|
|
34
|
+
const encodedPayload = base64url(Buffer.from(JSON.stringify(payload)));
|
|
35
|
+
const signingInput = `${encodedHeader}.${encodedPayload}`;
|
|
36
|
+
const signature = base64url(createHmac('sha256', secretKey).update(signingInput).digest());
|
|
37
|
+
|
|
38
|
+
return `${signingInput}.${signature}`;
|
|
39
|
+
}
|
package/src/lib/ws.ts
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import * as WS from 'ws';
|
|
2
|
+
import { uuid4 } from '../internal/utils/uuid';
|
|
3
|
+
import { createJwtToken } from './jwtAuth';
|
|
4
|
+
import { jsonParseFloat } from './jsonParseFloat';
|
|
5
|
+
import { buildURL as buildPublicURL } from '../resources/ws-public/internal-base';
|
|
6
|
+
import { buildURL as buildPrivateURL } from '../resources/ws-private/internal-base';
|
|
7
|
+
import type { ConnectPublicServerEvent } from '../resources/ws-public/ws-public';
|
|
8
|
+
import type { ConnectPrivateServerEvent } from '../resources/ws-private/ws-private';
|
|
9
|
+
import type { Upbit } from '../client';
|
|
10
|
+
|
|
11
|
+
export interface WsStreamOptions {
|
|
12
|
+
/** Maximum number of reconnection attempts (default: 5) */
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
/** Reconnection delay in ms (default: 1000) */
|
|
15
|
+
retryDelayMs?: number;
|
|
16
|
+
/** Callback invoked on disconnection */
|
|
17
|
+
onDisconnect?: (code: number, reason: string) => void;
|
|
18
|
+
/** Callback invoked on successful reconnection */
|
|
19
|
+
onReconnect?: () => void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
type PublicSubscriptionType =
|
|
23
|
+
| { type: 'ticker'; codes: string[] }
|
|
24
|
+
| { type: 'trade'; codes: string[] }
|
|
25
|
+
| { type: 'orderbook'; codes: string[] }
|
|
26
|
+
| { type: string; codes: string[] }; // candle.{interval}
|
|
27
|
+
|
|
28
|
+
type PrivateSubscriptionType = { type: 'myOrder'; codes?: string[] } | { type: 'myAsset' };
|
|
29
|
+
|
|
30
|
+
type AnySubscriptionType = PublicSubscriptionType | PrivateSubscriptionType;
|
|
31
|
+
|
|
32
|
+
function buildSubscriptionMessage(types: AnySubscriptionType[]): string {
|
|
33
|
+
const fields: object[] = [{ ticket: uuid4() }];
|
|
34
|
+
for (const t of types) {
|
|
35
|
+
if ('codes' in t && t.codes) {
|
|
36
|
+
fields.push({ type: t.type, codes: t.codes });
|
|
37
|
+
} else {
|
|
38
|
+
fields.push({ type: t.type });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return JSON.stringify(fields);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Manages a WebSocket stream as an AsyncIterable.
|
|
46
|
+
*
|
|
47
|
+
* Use with `for await (const event of manager) { ... }`.
|
|
48
|
+
*/
|
|
49
|
+
export class WsStreamManager implements AsyncIterable<ConnectPublicServerEvent | ConnectPrivateServerEvent> {
|
|
50
|
+
private readonly client: Upbit;
|
|
51
|
+
private readonly types: AnySubscriptionType[];
|
|
52
|
+
private readonly isPrivate: boolean;
|
|
53
|
+
private readonly maxRetries: number;
|
|
54
|
+
private readonly retryDelayMs: number;
|
|
55
|
+
private readonly onDisconnect: WsStreamOptions['onDisconnect'];
|
|
56
|
+
private readonly onReconnect: WsStreamOptions['onReconnect'];
|
|
57
|
+
private _currentWs: WS.WebSocket | null = null;
|
|
58
|
+
|
|
59
|
+
constructor(client: Upbit, types: AnySubscriptionType[], isPrivate: boolean, opts: WsStreamOptions = {}) {
|
|
60
|
+
this.client = client;
|
|
61
|
+
this.types = types;
|
|
62
|
+
this.isPrivate = isPrivate;
|
|
63
|
+
this.maxRetries = opts.maxRetries ?? 5;
|
|
64
|
+
this.retryDelayMs = opts.retryDelayMs ?? 1000;
|
|
65
|
+
if (opts.onDisconnect) this.onDisconnect = opts.onDisconnect;
|
|
66
|
+
if (opts.onReconnect) this.onReconnect = opts.onReconnect;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Closes the current WebSocket connection. */
|
|
70
|
+
close(): void {
|
|
71
|
+
if (
|
|
72
|
+
this._currentWs &&
|
|
73
|
+
(this._currentWs.readyState === WS.WebSocket.OPEN ||
|
|
74
|
+
this._currentWs.readyState === WS.WebSocket.CONNECTING)
|
|
75
|
+
) {
|
|
76
|
+
this._currentWs.close(1000, 'close() called');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[Symbol.asyncIterator](): AsyncGenerator<ConnectPublicServerEvent | ConnectPrivateServerEvent> {
|
|
81
|
+
return this._iterate();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private async *_iterate(): AsyncGenerator<ConnectPublicServerEvent | ConnectPrivateServerEvent> {
|
|
85
|
+
let retries = 0;
|
|
86
|
+
|
|
87
|
+
while (true) {
|
|
88
|
+
const queue: Array<ConnectPublicServerEvent | ConnectPrivateServerEvent> = [];
|
|
89
|
+
let resolve: (() => void) | null = null;
|
|
90
|
+
let reject: ((err: Error) => void) | null = null;
|
|
91
|
+
let done = false;
|
|
92
|
+
let closeCode = 1000;
|
|
93
|
+
let closeReason = '';
|
|
94
|
+
|
|
95
|
+
const ws = await this._connect();
|
|
96
|
+
this._currentWs = ws;
|
|
97
|
+
|
|
98
|
+
ws.on('message', (data: WS.RawData) => {
|
|
99
|
+
try {
|
|
100
|
+
const parsed = jsonParseFloat(data.toString()) as
|
|
101
|
+
| ConnectPublicServerEvent
|
|
102
|
+
| ConnectPrivateServerEvent;
|
|
103
|
+
queue.push(parsed);
|
|
104
|
+
resolve?.();
|
|
105
|
+
resolve = null;
|
|
106
|
+
} catch {
|
|
107
|
+
// ignore JSON parse errors
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
ws.on('close', (code: number, reason: Buffer) => {
|
|
112
|
+
done = true;
|
|
113
|
+
closeCode = code;
|
|
114
|
+
closeReason = reason.toString();
|
|
115
|
+
resolve?.();
|
|
116
|
+
resolve = null;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
ws.on('error', (err: Error) => {
|
|
120
|
+
done = true;
|
|
121
|
+
reject?.(err);
|
|
122
|
+
reject = null;
|
|
123
|
+
resolve?.();
|
|
124
|
+
resolve = null;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
while (!done || queue.length > 0) {
|
|
129
|
+
if (queue.length === 0) {
|
|
130
|
+
await new Promise<void>((res, rej) => {
|
|
131
|
+
resolve = res;
|
|
132
|
+
reject = rej;
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
while (queue.length > 0) {
|
|
136
|
+
yield queue.shift()!;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} finally {
|
|
140
|
+
this._currentWs = null;
|
|
141
|
+
if (ws.readyState === WS.WebSocket.OPEN || ws.readyState === WS.WebSocket.CONNECTING) {
|
|
142
|
+
ws.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// normal close (1000, 1001) — end the stream
|
|
147
|
+
if (closeCode === 1000 || closeCode === 1001) {
|
|
148
|
+
this.onDisconnect?.(closeCode, closeReason);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// attempt reconnect
|
|
153
|
+
this.onDisconnect?.(closeCode, closeReason);
|
|
154
|
+
|
|
155
|
+
if (retries >= this.maxRetries) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`WebSocket disconnected (code=${closeCode}, reason=${closeReason}) after ${retries} retries`,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
retries++;
|
|
162
|
+
await new Promise((r) => setTimeout(r, this.retryDelayMs));
|
|
163
|
+
this.onReconnect?.();
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private async _connect(): Promise<WS.WebSocket> {
|
|
168
|
+
const url = this.isPrivate ? buildPrivateURL(this.client) : buildPublicURL(this.client);
|
|
169
|
+
|
|
170
|
+
const headers: Record<string, string> = {};
|
|
171
|
+
|
|
172
|
+
if (this.isPrivate) {
|
|
173
|
+
const { accessKey, secretKey } = this.client;
|
|
174
|
+
if (!accessKey || !secretKey) {
|
|
175
|
+
throw new Error('Private WebSocket requires accessKey and secretKey');
|
|
176
|
+
}
|
|
177
|
+
const token = createJwtToken(accessKey, secretKey);
|
|
178
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return new Promise<WS.WebSocket>((resolve, reject) => {
|
|
182
|
+
const ws = new WS.WebSocket(url.toString(), { headers });
|
|
183
|
+
|
|
184
|
+
const onOpen = () => {
|
|
185
|
+
ws.removeListener('error', onError);
|
|
186
|
+
ws.send(buildSubscriptionMessage(this.types));
|
|
187
|
+
resolve(ws);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const onError = (err: Error) => {
|
|
191
|
+
ws.removeListener('open', onOpen);
|
|
192
|
+
reject(err);
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
ws.once('open', onOpen);
|
|
196
|
+
ws.once('error', onError);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Convenience API for WebSocket streams.
|
|
203
|
+
*
|
|
204
|
+
* Start a stream with `client.wsStream.ticker(['KRW-BTC'])` and
|
|
205
|
+
* receive events using `for await (const event of ...)`.
|
|
206
|
+
*/
|
|
207
|
+
export class WsStream {
|
|
208
|
+
constructor(private readonly client: Upbit) {}
|
|
209
|
+
|
|
210
|
+
/** Subscribe to the ticker (current price) stream. */
|
|
211
|
+
ticker(codes: string[], opts?: WsStreamOptions): WsStreamManager {
|
|
212
|
+
return new WsStreamManager(this.client, [{ type: 'ticker', codes }], false, opts);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Subscribe to the trade (executed order) stream. */
|
|
216
|
+
trade(codes: string[], opts?: WsStreamOptions): WsStreamManager {
|
|
217
|
+
return new WsStreamManager(this.client, [{ type: 'trade', codes }], false, opts);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/** Subscribe to the orderbook stream. */
|
|
221
|
+
orderbook(codes: string[], opts?: WsStreamOptions): WsStreamManager {
|
|
222
|
+
return new WsStreamManager(this.client, [{ type: 'orderbook', codes }], false, opts);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Subscribe to the candle stream. */
|
|
226
|
+
candle(codes: string[], opts?: { interval?: string } & WsStreamOptions): WsStreamManager {
|
|
227
|
+
const { interval = '1m', ...streamOpts } = opts ?? {};
|
|
228
|
+
return new WsStreamManager(this.client, [{ type: `candle.${interval}`, codes }], false, streamOpts);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** Subscribe to the myOrder (my orders) stream. Requires authentication. */
|
|
232
|
+
myOrder(codes: string[], opts?: WsStreamOptions): WsStreamManager {
|
|
233
|
+
return new WsStreamManager(this.client, [{ type: 'myOrder', codes }], true, opts);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Subscribe to the myAsset (my assets) stream. Requires authentication. */
|
|
237
|
+
myAsset(opts?: WsStreamOptions): WsStreamManager {
|
|
238
|
+
return new WsStreamManager(this.client, [{ type: 'myAsset' }], true, opts);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** Subscribe to multiple public streams at once. */
|
|
242
|
+
subscribe(
|
|
243
|
+
opts: {
|
|
244
|
+
ticker?: string[];
|
|
245
|
+
trade?: string[];
|
|
246
|
+
orderbook?: string[];
|
|
247
|
+
candle?: { codes: string[]; interval?: string };
|
|
248
|
+
} & WsStreamOptions,
|
|
249
|
+
): WsStreamManager {
|
|
250
|
+
const { ticker, trade, orderbook, candle, maxRetries, retryDelayMs, onDisconnect, onReconnect } = opts;
|
|
251
|
+
const types: AnySubscriptionType[] = [];
|
|
252
|
+
if (ticker) types.push({ type: 'ticker', codes: ticker });
|
|
253
|
+
if (trade) types.push({ type: 'trade', codes: trade });
|
|
254
|
+
if (orderbook) types.push({ type: 'orderbook', codes: orderbook });
|
|
255
|
+
if (candle) types.push({ type: `candle.${candle.interval ?? '1m'}`, codes: candle.codes });
|
|
256
|
+
const streamOpts: WsStreamOptions = {};
|
|
257
|
+
if (maxRetries !== undefined) streamOpts.maxRetries = maxRetries;
|
|
258
|
+
if (retryDelayMs !== undefined) streamOpts.retryDelayMs = retryDelayMs;
|
|
259
|
+
if (onDisconnect) streamOpts.onDisconnect = onDisconnect;
|
|
260
|
+
if (onReconnect) streamOpts.onReconnect = onReconnect;
|
|
261
|
+
return new WsStreamManager(this.client, types, false, streamOpts);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/** Subscribe to multiple private streams at once. Requires authentication. */
|
|
265
|
+
subscribePrivate(
|
|
266
|
+
opts: {
|
|
267
|
+
myOrder?: string[];
|
|
268
|
+
myAsset?: boolean;
|
|
269
|
+
} & WsStreamOptions,
|
|
270
|
+
): WsStreamManager {
|
|
271
|
+
const { myOrder, myAsset, maxRetries, retryDelayMs, onDisconnect, onReconnect } = opts;
|
|
272
|
+
const types: AnySubscriptionType[] = [];
|
|
273
|
+
if (myOrder) types.push({ type: 'myOrder', codes: myOrder });
|
|
274
|
+
if (myAsset) types.push({ type: 'myAsset' });
|
|
275
|
+
const streamOpts: WsStreamOptions = {};
|
|
276
|
+
if (maxRetries !== undefined) streamOpts.maxRetries = maxRetries;
|
|
277
|
+
if (retryDelayMs !== undefined) streamOpts.retryDelayMs = retryDelayMs;
|
|
278
|
+
if (onDisconnect) streamOpts.onDisconnect = onDisconnect;
|
|
279
|
+
if (onReconnect) streamOpts.onReconnect = onReconnect;
|
|
280
|
+
return new WsStreamManager(this.client, types, true, streamOpts);
|
|
281
|
+
}
|
|
282
|
+
}
|
package/src/resource.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
import { APIResource } from '../core/resource';
|
|
3
|
+
import { APIPromise } from '../core/api-promise';
|
|
4
|
+
import { RequestOptions } from '../internal/request-options';
|
|
5
|
+
|
|
6
|
+
export class Accounts extends APIResource {
|
|
7
|
+
/**
|
|
8
|
+
* Get Account Balances
|
|
9
|
+
*
|
|
10
|
+
* GET /v1/accounts
|
|
11
|
+
*
|
|
12
|
+
* - docs(kr): https://docs.upbit.com/kr/reference/get-balance
|
|
13
|
+
* - docs(global): https://global-docs.upbit.com/reference/get-balance
|
|
14
|
+
*/
|
|
15
|
+
list(options?: RequestOptions): APIPromise<AccountListResponse> {
|
|
16
|
+
return this._client.get('/v1/accounts', options);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type AccountListResponse = Array<AccountListResponse.AccountListResponseItem>;
|
|
21
|
+
|
|
22
|
+
export namespace AccountListResponse {
|
|
23
|
+
export interface AccountListResponseItem {
|
|
24
|
+
/**
|
|
25
|
+
* Average buy price of the asset.
|
|
26
|
+
*/
|
|
27
|
+
avg_buy_price: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Indicates whether the average buy price has been modified.
|
|
31
|
+
*/
|
|
32
|
+
avg_buy_price_modified: boolean;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Available amount or volume for orders. For digital assets, this represents the
|
|
36
|
+
* available quantity. For fiat currency, this represents the available amount.
|
|
37
|
+
*/
|
|
38
|
+
balance: string;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Currency code to be queried.
|
|
42
|
+
*/
|
|
43
|
+
currency: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Amount or quantity locked by pending orders or withdrawals.
|
|
47
|
+
*/
|
|
48
|
+
locked: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Currency unit used as the basis for avg_buy_price.
|
|
52
|
+
*/
|
|
53
|
+
unit_currency: string;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare namespace Accounts {
|
|
58
|
+
export { type AccountListResponse as AccountListResponse };
|
|
59
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
|
|
2
|
+
import { APIResource } from '../core/resource';
|
|
3
|
+
import { APIPromise } from '../core/api-promise';
|
|
4
|
+
import { RequestOptions } from '../internal/request-options';
|
|
5
|
+
|
|
6
|
+
export class APIKeys extends APIResource {
|
|
7
|
+
/**
|
|
8
|
+
* List API Keys
|
|
9
|
+
*
|
|
10
|
+
* GET /v1/api_keys
|
|
11
|
+
*
|
|
12
|
+
* - docs(kr): https://docs.upbit.com/kr/reference/list-api-keys
|
|
13
|
+
* - docs(global): https://global-docs.upbit.com/reference/list-api-keys
|
|
14
|
+
*/
|
|
15
|
+
list(options?: RequestOptions): APIPromise<APIKeyListResponse> {
|
|
16
|
+
return this._client.get('/v1/api_keys', options);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type APIKeyListResponse = Array<APIKeyListResponse.APIKeyListResponseItem>;
|
|
21
|
+
|
|
22
|
+
export namespace APIKeyListResponse {
|
|
23
|
+
export interface APIKeyListResponseItem {
|
|
24
|
+
/**
|
|
25
|
+
* Access key of the API key.
|
|
26
|
+
*/
|
|
27
|
+
access_key: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Expiration timestamp of the access key.
|
|
31
|
+
*
|
|
32
|
+
* [Format] yyyy-MM-dd'T'HH:mm:ss+09:00
|
|
33
|
+
*/
|
|
34
|
+
expire_at: string;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export declare namespace APIKeys {
|
|
39
|
+
export { type APIKeyListResponse as APIKeyListResponse };
|
|
40
|
+
}
|