From 393859c790b403dc49481cb401965fbfd28286fa Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 9 Oct 2026 17:45:04 +0800 Subject: [PATCH 1/4] docs: design API review fixes --- .../2026-10-09-api-review-fixes-design.md | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 docs/superpowers/specs/2026-10-09-api-review-fixes-design.md diff --git a/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md b/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md new file mode 100644 index 0000000..fb68e16 --- /dev/null +++ b/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md @@ -0,0 +1,30 @@ +# API Review Fixes Design + +## Goal + +Make the unreleased endpoint additions match the public Bybit V5 contract and avoid publishing wrappers that are undocumented, obsolete, or unusable. + +## Public API changes + +- Remove `AssetService::queryOrderFromOpen()` because `/v5/asset/exchange/query-order-list` is absent from the public documentation and failed every testnet request attempted during review. +- Remove `AssetService::coinConvertLimitQuery()` and `AssetService::limitOrderCallback()` because their endpoints are absent from the public documentation. Although the convert-limit endpoint currently responds on testnet, an official SDK should not promise an unsupported public contract. +- Remove `AssetService::assetInfoQuery()` and `AssetService::transferSubMemberSave()` because their documentation lives under the official `abandon` section. They are new, unreleased additions here, so removal does not break a released PHP API. +- Change `AccountService::getTradeInfoForAnalysis()` to require `string $symbol` and merge it into the signed query. +- Change `SpotMarginService::queryFixedBorrowMarket()` to require only `string $orderCurrency`; callers may pass optional `orderBy` through `$options`. + +## Documentation + +- Remove deleted methods from the `0.1.1` changelog entry. +- Update every newly added `@see` URL to the canonical public documentation route rather than assuming the endpoint path is also the documentation path. +- Keep the version bump and all other endpoint additions unchanged. + +## Tests + +- Add focused request-contract tests that assert the corrected method signatures, HTTP methods, paths, and serialized parameters. +- Add an inventory regression test asserting that the five removed methods are not part of the public service API. +- Run the full PHPUnit suite, PHPStan, PHP CS Fixer dry-run, syntax checks, and `git diff --check`. +- Re-run the corrected read-only methods against testnet. Do not run asset-moving or account-setting POST endpoints. + +## Compatibility and error handling + +All affected methods are unreleased working-tree additions, so correcting or removing them before release is preferable to carrying compatibility shims. Existing exception and response behavior remains unchanged. From 4d5f9d5fc8591192b1dd64c03bab4906e53c4006 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 9 Oct 2026 19:58:04 +0800 Subject: [PATCH 2/4] update sdk --- CHANGELOG.md | 68 ++++ src/Bybit.php | 2 +- src/RestApi/AccountService.php | 62 +++ src/RestApi/AssetService.php | 643 ++++++++++++++++++++++++++++++ src/RestApi/CryptoLoanService.php | 77 ++++ src/RestApi/EarnService.php | 34 ++ src/RestApi/MarketService.php | 15 + src/RestApi/PositionService.php | 23 ++ src/RestApi/SpotMarginService.php | 288 +++++++++++++ src/RestApi/UserService.php | 15 + tests/RestApiContractTest.php | 85 ++++ 11 files changed, 1311 insertions(+), 1 deletion(-) create mode 100644 tests/RestApiContractTest.php diff --git a/CHANGELOG.md b/CHANGELOG.md index e1d0cb8..9b10c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,72 @@ # Changelog +## 0.1.1 — 2026-10-09 + +### Added +- `AccountService::demoApplyMoney(...)` +- `AccountService::getOptionAssetInfo(...)` +- `AccountService::getPayInfo(...)` +- `AccountService::getTradeInfoForAnalysis(...)` +- `AssetService::getOverview(...)` +- `AssetService::getCoinGreeks(...)` +- `AssetService::queryCoinChainInfo(...)` +- `AssetService::smallAssetQuote(...)` +- `AssetService::smallAssetConvert(...)` +- `AssetService::querySmallAssetConvertOrder(...)` +- `AssetService::querySmallAssetList(...)` +- `AssetService::getDeliveryRecord(...)` +- `AssetService::setDefaultDepositToAccount(...)` +- `AssetService::queryDepositAddress(...)` +- `AssetService::queryInternalDepositRecords(...)` +- `AssetService::queryDepositRecords(...)` +- `AssetService::querySubMemberDepositAddress(...)` +- `AssetService::querySubMemberDepositRecords(...)` +- `AssetService::convertExecute(...)` +- `AssetService::queryResult(...)` +- `AssetService::queryOrderByPage(...)` +- `AssetService::coinListQuery(...)` +- `AssetService::convertHistoryQuery(...)` +- `AssetService::quoteApply(...)` +- `AssetService::getPortfolioMargin(...)` +- `AssetService::getSettlementRecord(...)` +- `AssetService::getTotalMembersAssets(...)` +- `AssetService::interTransfer(...)` +- `AssetService::accountCoinBalanceQuery(...)` +- `AssetService::interTransferListQuery(...)` +- `AssetService::subMemberListQuery(...)` +- `AssetService::transferCoinListQuery(...)` +- `AssetService::universalTransferListQuery(...)` +- `AssetService::universalTransfer(...)` +- `AssetService::cancelWithdraw(...)` +- `AssetService::sendWithdraw(...)` +- `AssetService::queryWithdrawAddresses(...)` +- `AssetService::queryWithdrawRecords(...)` +- `AssetService::getVaspList(...)` +- `AssetService::getWithdrawableAmountByCoin(...)` +- `CryptoLoanService::getFixedAvailableInventory(...)` +- `CryptoLoanService::getFixedRepaymentHistory(...)` +- `CryptoLoanService::supplyFixed(...)` +- `CryptoLoanService::getFlexibleAvailableInventory(...)` +- `EarnService::listAutoSavings(...)` +- `EarnService::editEarnAutoSavings(...)` +- `MarketService::getOptionBaseCoins(...)` +- `PositionService::getSymbolInfo(...)` +- `SpotMarginService::getTradeCoinState(...)` +- `SpotMarginService::queryFixedAvailableInventory(...)` +- `SpotMarginService::accountFixedBorrow(...)` +- `SpotMarginService::queryFixedBorrowContracts(...)` +- `SpotMarginService::queryFixedBorrowOrders(...)` +- `SpotMarginService::queryFixedBorrowMarket(...)` +- `SpotMarginService::renewFixedBorrow(...)` +- `SpotMarginService::getTradeFlexibleAvailableInventory(...)` +- `SpotMarginService::getTradeAutoRepayMode(...)` +- `SpotMarginService::queryBorrowLiability(...)` +- `SpotMarginService::getTradeMaxBorrowable(...)` +- `SpotMarginService::getTradeRepaymentAvailableAmount(...)` +- `SpotMarginService::setAutoRepayMode(...)` +- `SpotMarginService::spotMarginSetLeverage(...)` +- `SpotMarginService::getTradeState(...)` +- `SpotMarginService::spotMarginSwitchMode(...)` +- `UserService::queryReferralCode(...)` All notable changes to this project will be documented in this file. diff --git a/src/Bybit.php b/src/Bybit.php index 8d457ca..18a2013 100644 --- a/src/Bybit.php +++ b/src/Bybit.php @@ -9,7 +9,7 @@ */ final class Bybit { - public const VERSION = '0.1.0'; + public const VERSION = '0.1.1'; public const BASE_URL_MAINNET = 'https://api.bybit.com'; public const BASE_URL_TESTNET = 'https://api-testnet.bybit.com'; diff --git a/src/RestApi/AccountService.php b/src/RestApi/AccountService.php index 05f9696..57b85a2 100644 --- a/src/RestApi/AccountService.php +++ b/src/RestApi/AccountService.php @@ -424,4 +424,66 @@ public function upgradeToUtaPro(array $options = []): array { return $this->session->signRequest('POST', '/v5/account/upgrade-to-uta', $options); } + + /** + * Apply demo funds + * + * POST /v5/account/demo-apply-money + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/demo#request-demo-trading-funds + */ + public function demoApplyMoney(array $options = []): array + { + return $this->session->signRequest('POST', '/v5/account/demo-apply-money', $options); + } + + /** + * Get Option Asset Info + * + * GET /v5/account/option-asset-info + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/account/option-asset-info + */ + public function getOptionAssetInfo(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/account/option-asset-info', $options); + } + + /** + * Get Pay Info + * + * GET /v5/account/pay-info + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/account/pay-info + */ + public function getPayInfo(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/account/pay-info', $options); + } + + /** + * Get Trade Info For Analysis + * + * GET /v5/account/trade-info-for-analysis + * + * @param string $symbol Symbol name, e.g. `BTCUSDT`, `ETHUSDT`. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/account/trade-info-for-analysis + */ + public function getTradeInfoForAnalysis(string $symbol, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/account/trade-info-for-analysis', + array_merge($options, ['symbol' => $symbol]) + ); + } + } diff --git a/src/RestApi/AssetService.php b/src/RestApi/AssetService.php index ff6546a..8ca7a8d 100644 --- a/src/RestApi/AssetService.php +++ b/src/RestApi/AssetService.php @@ -38,4 +38,647 @@ public function queryFundingDetail(array $options = []): array { return $this->session->signRequest('GET', '/v5/asset/fundinghistory', $options); } + + /** + * Get Asset Overview + * + * GET /v5/asset/asset-overview + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/balance/asset-overview + */ + public function getOverview(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/asset-overview', $options); + } + + /** + * Get Coin Greeks + * + * GET /v5/asset/coin-greeks + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/account/coin-greeks + */ + public function getCoinGreeks(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/coin-greeks', $options); + } + + /** + * Get Coin Info + * + * GET /v5/asset/coin/query-info + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/coin-info + */ + public function queryCoinChainInfo(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/coin/query-info', $options); + } + + /** + * Small asset get quote + * + * POST /v5/asset/covert/get-quote + * + * @param string $accountType Wallet type. Only supports eb_convert_uta (Unified wallet) + * @param string $toCoin Target currency. Each request supports one of: MNT, USDT, or USDC + * @param array $fromCoinList Source currency list, e.g. ["BTC","XRP","ETH"]. Up to 20 coins per transaction + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert-small-balance/request-quote + */ + public function smallAssetQuote(string $accountType, string $toCoin, array $fromCoinList, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/covert/get-quote', + array_merge($options, ['accountType' => $accountType, 'toCoin' => $toCoin, 'fromCoinList' => $fromCoinList]) + ); + } + + /** + * Small asset confirm conversion + * + * POST /v5/asset/covert/small-balance-execute + * + * @param string $quoteId Quote ID from the get-quote interface (/v5/asset/covert/get-quote) + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert-small-balance/confirm-quote + */ + public function smallAssetConvert(string $quoteId, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/covert/small-balance-execute', + array_merge($options, ['quoteId' => $quoteId]) + ); + } + + /** + * Small asset conversion history query + * + * GET /v5/asset/covert/small-balance-history + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert-small-balance/exchange-history + */ + public function querySmallAssetConvertOrder(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/covert/small-balance-history', $options); + } + + /** + * Small asset conversion list query + * + * GET /v5/asset/covert/small-balance-list + * + * @param string $accountType Wallet type. Only supports eb_convert_uta (Unified wallet) + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert-small-balance/small-balanc-coins + */ + public function querySmallAssetList(string $accountType, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/covert/small-balance-list', + array_merge($options, ['accountType' => $accountType]) + ); + } + + /** + * Get Delivery Record + * + * GET /v5/asset/delivery-record + * + * @param string $category Product type: +- `linear`: USDT / USDC futures +- `inverse`: Inverse futures +- `option`: Options + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/delivery + */ + public function getDeliveryRecord(string $category, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/delivery-record', + array_merge($options, ['category' => $category]) + ); + } + + /** + * Set Deposit Account + * + * POST /v5/asset/deposit/deposit-to-account + * + * @param string $accountType Deposit target account type: +- `UNIFIED`: Unified Trading Account +- `FUND`: Fund Account (default) + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/set-deposit-acct + */ + public function setDefaultDepositToAccount(string $accountType, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/deposit/deposit-to-account', + array_merge($options, ['accountType' => $accountType]) + ); + } + + /** + * Get Master Deposit Address + * + * GET /v5/asset/deposit/query-address + * + * @param string $coin Coin symbol (uppercase only), e.g. `USDT`. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/master-deposit-addr + */ + public function queryDepositAddress(string $coin, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/deposit/query-address', + array_merge($options, ['coin' => $coin]) + ); + } + + /** + * Get Internal Deposit Records (off-chain) + * + * GET /v5/asset/deposit/query-internal-record + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/internal-deposit-record + */ + public function queryInternalDepositRecords(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/deposit/query-internal-record', $options); + } + + /** + * Get Deposit Records (on-chain) + * + * GET /v5/asset/deposit/query-record + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/deposit-record + */ + public function queryDepositRecords(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/deposit/query-record', $options); + } + + /** + * Get Sub Deposit Address + * + * GET /v5/asset/deposit/query-sub-member-address + * + * @param string $coin Coin symbol (uppercase only). + * @param string $chainType Chain type. Use `chain` value from the coin-info endpoint. + * @param string $subMemberId Sub-account user ID. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/sub-deposit-addr + */ + public function querySubMemberDepositAddress(string $coin, string $chainType, string $subMemberId, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/deposit/query-sub-member-address', + array_merge($options, ['coin' => $coin, 'chainType' => $chainType, 'subMemberId' => $subMemberId]) + ); + } + + /** + * Get Sub Deposit Records (on-chain) + * + * GET /v5/asset/deposit/query-sub-member-record + * + * @param string $subMemberId Sub-account UID. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/deposit/sub-deposit-record + */ + public function querySubMemberDepositRecords(string $subMemberId, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/deposit/query-sub-member-record', + array_merge($options, ['subMemberId' => $subMemberId]) + ); + } + + /** + * Execute conversion + * + * POST /v5/asset/exchange/convert-execute + * + * @param string $quoteTxId Quote transaction ID returned by the QuoteApply interface + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert/confirm-quote + */ + public function convertExecute(string $quoteTxId, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/exchange/convert-execute', + array_merge($options, ['quoteTxId' => $quoteTxId]) + ); + } + + /** + * Query conversion result + * + * GET /v5/asset/exchange/convert-result-query + * + * @param string $quoteTxId Quote transaction ID + * @param string $accountType Wallet type (scene code) + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-result + */ + public function queryResult(string $quoteTxId, string $accountType, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/exchange/convert-result-query', + array_merge($options, ['quoteTxId' => $quoteTxId, 'accountType' => $accountType]) + ); + } + + /** + * Paginated conversion order query + * + * GET /v5/asset/exchange/order-record + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/exchange + */ + public function queryOrderByPage(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/exchange/order-record', $options); + } + + /** + * Coin list query + * + * GET /v5/asset/exchange/query-coin-list + * + * @param string $accountType Wallet type. Supported values: eb_convert_funding, eb_convert_uta, eb_convert_spot, eb_convert_contract, eb_convert_inverse + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert/convert-coin-list + */ + public function coinListQuery(string $accountType, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/exchange/query-coin-list', + array_merge($options, ['accountType' => $accountType]) + ); + } + + /** + * Conversion history query + * + * GET /v5/asset/exchange/query-convert-history + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert/get-convert-history + */ + public function convertHistoryQuery(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/exchange/query-convert-history', $options); + } + + /** + * Apply quote + * + * POST /v5/asset/exchange/quote-apply + * + * @param string $accountType Wallet type (required) + * @param string $fromCoin Convert from coin (coin to sell), required + * @param string $toCoin Convert to coin (coin to buy), required + * @param string $requestAmount Request coin amount (the amount you want to sell), required + * @param string $requestCoin Request coin, same as fromCoin, required + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/convert/apply-quote + */ + public function quoteApply(string $accountType, string $fromCoin, string $toCoin, string $requestAmount, string $requestCoin, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/exchange/quote-apply', + array_merge($options, ['accountType' => $accountType, 'fromCoin' => $fromCoin, 'toCoin' => $toCoin, 'requestAmount' => $requestAmount, 'requestCoin' => $requestCoin]) + ); + } + + /** + * Get Portfolio Margin Info + * + * GET /v5/asset/portfolio-margin + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/portfolio-margin + */ + public function getPortfolioMargin(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/portfolio-margin', $options); + } + + /** + * Get USDC Session Settlement + * + * GET /v5/asset/settlement-record + * + * @param string $category Product type: +- `linear`: USDC contract + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/settlement + */ + public function getSettlementRecord(string $category, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/settlement-record', + array_merge($options, ['category' => $category]) + ); + } + + /** + * Get Total Members Assets + * + * GET /v5/asset/total-members-assets + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/total-members-assets + */ + public function getTotalMembersAssets(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/total-members-assets', $options); + } + + /** + * Create Internal Transfer + * + * POST /v5/asset/transfer/inter-transfer + * + * @param string $transferId UUID for the transfer. Must be unique and manually generated by client. + * @param string $coin Coin name, uppercase (e.g. BTC, USDT) + * @param string $amount Transfer amount. Must be greater than zero. String format for precision. + * @param string $fromAccountType Source account type + * @param string $toAccountType Destination account type + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/transfer/create-inter-transfer + */ + public function interTransfer(string $transferId, string $coin, string $amount, string $fromAccountType, string $toAccountType, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/transfer/inter-transfer', + array_merge($options, ['transferId' => $transferId, 'coin' => $coin, 'amount' => $amount, 'fromAccountType' => $fromAccountType, 'toAccountType' => $toAccountType]) + ); + } + + /** + * Get Single Coin Balance + * + * GET /v5/asset/transfer/query-account-coin-balance + * + * @param string $accountType Account type + * @param string $coin Coin name, uppercase (e.g. USDT, BTC). Required. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/balance/account-coin-balance + */ + public function accountCoinBalanceQuery(string $accountType, string $coin, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/transfer/query-account-coin-balance', + array_merge($options, ['accountType' => $accountType, 'coin' => $coin]) + ); + } + + /** + * Get Internal Transfer Records + * + * GET /v5/asset/transfer/query-inter-transfer-list + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/transfer/inter-transfer-list + */ + public function interTransferListQuery(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/transfer/query-inter-transfer-list', $options); + } + + /** + * Get Sub UID List + * + * GET /v5/asset/transfer/query-sub-member-list + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/sub-uid-list + */ + public function subMemberListQuery(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/transfer/query-sub-member-list', $options); + } + + /** + * Get Transferable Coin List + * + * GET /v5/asset/transfer/query-transfer-coin-list + * + * @param string $fromAccountType Source account type + * @param string $toAccountType Destination account type + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/transfer/transferable-coin + */ + public function transferCoinListQuery(string $fromAccountType, string $toAccountType, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/transfer/query-transfer-coin-list', + array_merge($options, ['fromAccountType' => $fromAccountType, 'toAccountType' => $toAccountType]) + ); + } + + /** + * Get Universal Transfer Records + * + * GET /v5/asset/transfer/query-universal-transfer-list + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/transfer/unitransfer-list + */ + public function universalTransferListQuery(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/transfer/query-universal-transfer-list', $options); + } + + /** + * Create Universal Transfer + * + * POST /v5/asset/transfer/universal-transfer + * + * @param string $transferId UUID for the transfer + * @param string $coin Coin name, uppercase + * @param string $amount Transfer amount, must be greater than zero + * @param int $fromMemberId Source UID + * @param int $toMemberId Destination UID + * @param string $fromAccountType Source account type + * @param string $toAccountType Destination account type + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/transfer/unitransfer + */ + public function universalTransfer(string $transferId, string $coin, string $amount, int $fromMemberId, int $toMemberId, string $fromAccountType, string $toAccountType, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/transfer/universal-transfer', + array_merge($options, ['transferId' => $transferId, 'coin' => $coin, 'amount' => $amount, 'fromMemberId' => $fromMemberId, 'toMemberId' => $toMemberId, 'fromAccountType' => $fromAccountType, 'toAccountType' => $toAccountType]) + ); + } + + /** + * Cancel Withdrawal + * + * POST /v5/asset/withdraw/cancel + * + * @param string $id Withdrawal ID to cancel + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/withdraw/cancel-withdraw + */ + public function cancelWithdraw(string $id, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/withdraw/cancel', + array_merge($options, ['id' => $id]) + ); + } + + /** + * Withdraw + * + * POST /v5/asset/withdraw/create + * + * @param string $coin Coin name, uppercase + * @param string $address Wallet address (forceChain=0/1) or Bybit main account UID (forceChain=2) + * @param string $amount Withdrawal amount (string). Must be greater than 0 and meet coin precision requirements + * @param int $timestamp Current timestamp in milliseconds. Used for replay attack prevention + * @param string $accountType Account type to deduct from. Supports combo: +- `FUND`: Funding account +- `UTA`: Unified Trading Account +- `FUND,UTA`: Deduct from FUND first, then UTA for remainder + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/withdraw/withdraw + */ + public function sendWithdraw(string $coin, string $address, string $amount, int $timestamp, string $accountType, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/asset/withdraw/create', + array_merge($options, ['coin' => $coin, 'address' => $address, 'amount' => $amount, 'timestamp' => $timestamp, 'accountType' => $accountType]) + ); + } + + /** + * Get Withdrawal Address List + * + * GET /v5/asset/withdraw/query-address + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/withdraw/withdraw-address + */ + public function queryWithdrawAddresses(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/withdraw/query-address', $options); + } + + /** + * Get Withdrawal Records + * + * GET /v5/asset/withdraw/query-record + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/withdraw/withdraw-record + */ + public function queryWithdrawRecords(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/withdraw/query-record', $options); + } + + /** + * Get Available VASPs + * + * GET /v5/asset/withdraw/vasp/list + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/withdraw/vasp-list + */ + public function getVaspList(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/asset/withdraw/vasp/list', $options); + } + + /** + * Get Withdrawable Amount + * + * GET /v5/asset/withdraw/withdrawable-amount + * + * @param string $coin Coin name, uppercase, e.g. USDT + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/asset/balance/delay-amount + */ + public function getWithdrawableAmountByCoin(string $coin, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/asset/withdraw/withdrawable-amount', + array_merge($options, ['coin' => $coin]) + ); + } + } diff --git a/src/RestApi/CryptoLoanService.php b/src/RestApi/CryptoLoanService.php index 2867ccf..2bd139e 100644 --- a/src/RestApi/CryptoLoanService.php +++ b/src/RestApi/CryptoLoanService.php @@ -446,4 +446,81 @@ public function repayFlexibleWithCollateral(string $loanCurrency, string $collat array_merge($options, ['loanCurrency' => $loanCurrency, 'collateralCoin' => $collateralCoin, 'amount' => $amount]) ); } + + /** + * Get Available Inventory + * + * GET /v5/crypto-loan-fixed/available-inventory + * + * @param string $currency Coin name, uppercase only + * @param string $term Fixed term 7: 7 days; 14: 14 days; 30: 30 days; 90: 90 days; 180: 180 days + * @param string $annualRate Customizable annual interest rate, e.g., 0.02 means 2% + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/new-crypto-loan/fixed/available-inventory + */ + public function getFixedAvailableInventory(string $currency, string $term, string $annualRate, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/crypto-loan-fixed/available-inventory', + array_merge($options, ['currency' => $currency, 'term' => $term, 'annualRate' => $annualRate]) + ); + } + + /** + * Get Repayment History + * + * GET /v5/crypto-loan-fixed/repayment-history + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/new-crypto-loan/fixed/repay-history + */ + public function getFixedRepaymentHistory(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/crypto-loan-fixed/repayment-history', $options); + } + + /** + * Create Supply Order + * + * POST /v5/crypto-loan-fixed/supply + * + * @param string $orderCurrency Currency to lend + * @param string $orderAmount Amount to lend + * @param string $annualRate Annual interest rate + * @param string $term Term in days (7, 14, 30, 60, 90, 180) + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/new-crypto-loan/fixed/supply + */ + public function supplyFixed(string $orderCurrency, string $orderAmount, string $annualRate, string $term, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/crypto-loan-fixed/supply', + array_merge($options, ['orderCurrency' => $orderCurrency, 'orderAmount' => $orderAmount, 'annualRate' => $annualRate, 'term' => $term]) + ); + } + + /** + * Get Available Inventory + * + * GET /v5/crypto-loan-flexible/available-inventory + * + * @param string $currency Coin name, uppercase only + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/new-crypto-loan/flexible/available-inventory + */ + public function getFlexibleAvailableInventory(string $currency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/crypto-loan-flexible/available-inventory', + array_merge($options, ['currency' => $currency]) + ); + } + } diff --git a/src/RestApi/EarnService.php b/src/RestApi/EarnService.php index dc56a4e..bf0dad4 100644 --- a/src/RestApi/EarnService.php +++ b/src/RestApi/EarnService.php @@ -1297,4 +1297,38 @@ public function setFixedTermAutoInvest(string $productId, string $category, stri array_merge($options, ['productId' => $productId, 'category' => $category, 'positionId' => $positionId, 'status' => $status]) ); } + + /** + * Get Auto Savings Settings + * + * GET /v5/earn/flexible-saving/auto-savings + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/finance/earn/flexible-saving/auto-savings + */ + public function listAutoSavings(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/earn/flexible-saving/auto-savings', $options); + } + + /** + * Edit Auto Savings Settings + * + * POST /v5/earn/flexible-saving/auto-savings + * + * @param bool $isSelected Whether to enable auto savings + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/finance/earn/flexible-saving/auto-savings + */ + public function editEarnAutoSavings(bool $isSelected, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/earn/flexible-saving/auto-savings', + array_merge($options, ['isSelected' => $isSelected]) + ); + } + } diff --git a/src/RestApi/MarketService.php b/src/RestApi/MarketService.php index 56268e8..418cd39 100644 --- a/src/RestApi/MarketService.php +++ b/src/RestApi/MarketService.php @@ -426,4 +426,19 @@ public function getTickers(string $category, array $options = []): array array_merge($options, ['category' => $category]) ); } + + /** + * Get Option Base Coins + * + * GET /v5/market/option-base-coins + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/market/option-base-coins + */ + public function getOptionBaseCoins(array $options = []): array + { + return $this->session->publicRequest('GET', '/v5/market/option-base-coins', $options); + } + } diff --git a/src/RestApi/PositionService.php b/src/RestApi/PositionService.php index 7180513..acb5295 100644 --- a/src/RestApi/PositionService.php +++ b/src/RestApi/PositionService.php @@ -236,4 +236,27 @@ public function switchPositionMode(string $category, int $mode, array $options = array_merge($options, ['category' => $category, 'mode' => $mode]) ); } + + /** + * Get Futures Leverage + * + * GET /v5/position/symbol-info + * + * @param string $category Product type: +- `linear`: USDT perpetual, USDC contract +- `inverse`: Inverse perpetual, Inverse futures + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/position/batch-lvg + */ + public function getSymbolInfo(string $category, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/position/symbol-info', + array_merge($options, ['category' => $category]) + ); + } + } diff --git a/src/RestApi/SpotMarginService.php b/src/RestApi/SpotMarginService.php index 917c15d..b2a14b6 100644 --- a/src/RestApi/SpotMarginService.php +++ b/src/RestApi/SpotMarginService.php @@ -66,4 +66,292 @@ public function getVipMarginData(array $options = []): array { return $this->session->publicRequest('GET', '/v5/spot-margin-trade/data', $options); } + + /** + * Get Spot Margin Coin State + * + * GET /v5/spot-margin-trade/coinstate + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/coinstate + */ + public function getTradeCoinState(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/spot-margin-trade/coinstate', $options); + } + + /** + * Query Fixed-Rate Available Inventory + * + * GET /v5/spot-margin-trade/fixed-available-inventory + * + * @param string $currency Borrow coin name, uppercase only. e.g. `USDT`, `BTC`. **Required.** + * @param string $term Loan term in days. e.g. `7`, `14`, `30`, `90`, `180`. **Required.** + * @param string $annualRate Annual interest rate. e.g. `0.02` means 2%. **Required.** + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixed-available-inventory + */ + public function queryFixedAvailableInventory(string $currency, string $term, string $annualRate, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/fixed-available-inventory', + array_merge($options, ['currency' => $currency, 'term' => $term, 'annualRate' => $annualRate]) + ); + } + + /** + * Fixed-Rate Borrow + * + * POST /v5/spot-margin-trade/fixedborrow + * + * @param string $orderCurrency Borrow coin name, uppercase only. e.g. `USDT`, `BTC`. + * @param string $orderAmount Borrow amount. + * @param string $annualRate Annual interest rate. e.g. `0.02` means 2%. + * @param string $term Loan term in days. Supported values: `7`, `14`, `30`, `90`, `180`. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow + */ + public function accountFixedBorrow(string $orderCurrency, string $orderAmount, string $annualRate, string $term, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/spot-margin-trade/fixedborrow', + array_merge($options, ['orderCurrency' => $orderCurrency, 'orderAmount' => $orderAmount, 'annualRate' => $annualRate, 'term' => $term]) + ); + } + + /** + * Query Fixed-Rate Borrow Contracts + * + * GET /v5/spot-margin-trade/fixedborrow-contract-info + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-contract-info + */ + public function queryFixedBorrowContracts(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/spot-margin-trade/fixedborrow-contract-info', $options); + } + + /** + * Query Fixed-Rate Borrow Orders + * + * GET /v5/spot-margin-trade/fixedborrow-order-info + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-order-info + */ + public function queryFixedBorrowOrders(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/spot-margin-trade/fixedborrow-order-info', $options); + } + + /** + * Query Fixed-Rate Borrow Market + * + * GET /v5/spot-margin-trade/fixedborrow-order-quote + * + * @param string $orderCurrency Borrow coin name, uppercase only. e.g. `USDT`, `BTC`. + * @param array{term?:string, orderBy?:string, sort?:int, limit?:int} $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-order-quote + */ + public function queryFixedBorrowMarket(string $orderCurrency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/fixedborrow-order-quote', + array_merge($options, ['orderCurrency' => $orderCurrency]) + ); + } + + /** + * Renew Fixed-Rate Borrow + * + * POST /v5/spot-margin-trade/fixedborrow-renew + * + * @param string $loanId The loan contract ID (corresponds to match order ID). Required. + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/fixedborrow-renew + */ + public function renewFixedBorrow(string $loanId, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/spot-margin-trade/fixedborrow-renew', + array_merge($options, ['loanId' => $loanId]) + ); + } + + /** + * Get Flexible Available Inventory + * + * GET /v5/spot-margin-trade/flexible-available-inventory + * + * @param string $currency Coin name, uppercase only. e.g. `BTC` + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/flexible-available-inventory + */ + public function getTradeFlexibleAvailableInventory(string $currency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/flexible-available-inventory', + array_merge($options, ['currency' => $currency]) + ); + } + + /** + * Get Auto Repay Mode + * + * GET /v5/spot-margin-trade/get-auto-repay-mode + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/get-auto-repay-mode + */ + public function getTradeAutoRepayMode(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/spot-margin-trade/get-auto-repay-mode', $options); + } + + /** + * Query Borrow Liability + * + * GET /v5/spot-margin-trade/liability + * + * @param string $currency Coin name, uppercase only. e.g. `USDT`, `BTC`. **Required.** + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/liability + */ + public function queryBorrowLiability(string $currency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/liability', + array_merge($options, ['currency' => $currency]) + ); + } + + /** + * Get Max Borrowable Amount + * + * GET /v5/spot-margin-trade/max-borrowable + * + * @param string $currency Coin name, uppercase only. e.g. `BTC` + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/max-borrowable + */ + public function getTradeMaxBorrowable(string $currency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/max-borrowable', + array_merge($options, ['currency' => $currency]) + ); + } + + /** + * Get Repayment Available Amount + * + * GET /v5/spot-margin-trade/repayment-available-amount + * + * @param string $currency Coin name, uppercase only. e.g. `BTC` + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/repayment-available-amount + */ + public function getTradeRepaymentAvailableAmount(string $currency, array $options = []): array + { + return $this->session->signRequest( + 'GET', + '/v5/spot-margin-trade/repayment-available-amount', + array_merge($options, ['currency' => $currency]) + ); + } + + /** + * Set Auto Repay Mode + * + * POST /v5/spot-margin-trade/set-auto-repay-mode + * + * @param string $autoRepayMode Auto repay mode switch: +- `1`: Enable auto repay — Enable auto repay +- `0`: Disable auto repay — Disable auto repay + + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/set-auto-repay-mode + */ + public function setAutoRepayMode(string $autoRepayMode, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/spot-margin-trade/set-auto-repay-mode', + array_merge($options, ['autoRepayMode' => $autoRepayMode]) + ); + } + + /** + * Set spot cross margin leverage + * + * POST /v5/spot-margin-trade/set-leverage + * + * @param string $leverage Leverage amount, valid range is 2 to 10 + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/set-leverage + */ + public function spotMarginSetLeverage(string $leverage, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/spot-margin-trade/set-leverage', + array_merge($options, ['leverage' => $leverage]) + ); + } + + /** + * Get Spot Margin Trade Status + * + * GET /v5/spot-margin-trade/state + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/status + */ + public function getTradeState(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/spot-margin-trade/state', $options); + } + + /** + * Toggle spot cross margin mode + * + * POST /v5/spot-margin-trade/switch-mode + * + * @param string $spotMarginMode Spot margin mode: 1=on, 0=off + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/spot-margin-uta/switch-mode + */ + public function spotMarginSwitchMode(string $spotMarginMode, array $options = []): array + { + return $this->session->signRequest( + 'POST', + '/v5/spot-margin-trade/switch-mode', + array_merge($options, ['spotMarginMode' => $spotMarginMode]) + ); + } + } diff --git a/src/RestApi/UserService.php b/src/RestApi/UserService.php index af4b310..e5763e8 100644 --- a/src/RestApi/UserService.php +++ b/src/RestApi/UserService.php @@ -294,4 +294,19 @@ public function updateSubApiKey(int $subuid, int $readOnly, array $options = []) array_merge($options, ['subuid' => $subuid, 'readOnly' => $readOnly]) ); } + + /** + * Query Referral Code + * + * GET /v5/user/invitation/code + * + * @param array $options + * @return array Bybit V5 ApiResponse envelope (retCode / retMsg / result / retExtInfo / time). + * @see https://bybit-exchange.github.io/docs/v5/user/referral-code + */ + public function queryReferralCode(array $options = []): array + { + return $this->session->signRequest('GET', '/v5/user/invitation/code', $options); + } + } diff --git a/tests/RestApiContractTest.php b/tests/RestApiContractTest.php new file mode 100644 index 0000000..6e65d06 --- /dev/null +++ b/tests/RestApiContractTest.php @@ -0,0 +1,85 @@ + */ + public static function removedAssetMethodProvider(): iterable + { + foreach ([ + 'queryOrderFromOpen', + 'coinConvertLimitQuery', + 'limitOrderCallback', + 'assetInfoQuery', + 'transferSubMemberSave', + ] as $method) { + yield $method => [$method]; + } + } + + public function testTradeInfoForAnalysisRequiresAndSendsSymbol(): void + { + $history = []; + $client = $this->makeClient($history); + + $client->account->getTradeInfoForAnalysis('BTCUSDT', ['startTime' => 1000]); + + $this->assertCount(1, $history); + $request = $history[0]['request']; + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/v5/account/trade-info-for-analysis', $request->getUri()->getPath()); + $this->assertSame('startTime=1000&symbol=BTCUSDT', $request->getUri()->getQuery()); + } + + public function testFixedBorrowMarketKeepsOrderByOptional(): void + { + $history = []; + $client = $this->makeClient($history); + + $client->spotMargin->queryFixedBorrowMarket('USDT', ['orderBy' => 'apy', 'limit' => 1]); + + $this->assertCount(1, $history); + $request = $history[0]['request']; + $this->assertSame('GET', $request->getMethod()); + $this->assertSame('/v5/spot-margin-trade/fixedborrow-order-quote', $request->getUri()->getPath()); + $this->assertSame('limit=1&orderBy=apy&orderCurrency=USDT', $request->getUri()->getQuery()); + } + + /** @dataProvider removedAssetMethodProvider */ + public function testUnsupportedOrAbandonedAssetMethodIsNotPublished(string $method): void + { + $this->assertFalse(method_exists(\Bybit\RestApi\AssetService::class, $method)); + } + + /** @param array> $history */ + private function makeClient(array &$history): Client + { + $mock = new MockHandler([ + new Response(200, ['Content-Type' => 'application/json'], '{"retCode":0,"retMsg":"OK","result":{},"retExtInfo":{},"time":0}'), + ]); + $stack = HandlerStack::create($mock); + $stack->push(Middleware::history($history)); + + return new Client(new Configuration( + apiKey: 'test-key', + apiSecret: 'test-secret', + httpClient: new GuzzleClient([ + 'handler' => $stack, + 'base_uri' => 'https://api-testnet.bybit.com', + 'http_errors' => false, + ]), + )); + } +} From 45d9c7e0d49a013fde4240cd6ffa25937de4b184 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 9 Oct 2026 20:16:53 +0800 Subject: [PATCH 3/4] update sdk --- src/RestApi/AccountService.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/RestApi/AccountService.php b/src/RestApi/AccountService.php index 57b85a2..a2373ed 100644 --- a/src/RestApi/AccountService.php +++ b/src/RestApi/AccountService.php @@ -428,6 +428,9 @@ public function upgradeToUtaPro(array $options = []): array /** * Apply demo funds * + * Demo Trading only. Configure `baseUrl: 'https://api-demo.bybit.com'`; + * `testnet: true` uses api-testnet.bybit.com and cannot call this endpoint. + * * POST /v5/account/demo-apply-money * * @param array $options From 149cbdb79e0f100d492c18d094ea6a282792c392 Mon Sep 17 00:00:00 2001 From: doris-xiao-bybit Date: Fri, 9 Oct 2026 20:24:00 +0800 Subject: [PATCH 4/4] update sdk --- .../2026-10-09-api-review-fixes-design.md | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 docs/superpowers/specs/2026-10-09-api-review-fixes-design.md diff --git a/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md b/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md deleted file mode 100644 index fb68e16..0000000 --- a/docs/superpowers/specs/2026-10-09-api-review-fixes-design.md +++ /dev/null @@ -1,30 +0,0 @@ -# API Review Fixes Design - -## Goal - -Make the unreleased endpoint additions match the public Bybit V5 contract and avoid publishing wrappers that are undocumented, obsolete, or unusable. - -## Public API changes - -- Remove `AssetService::queryOrderFromOpen()` because `/v5/asset/exchange/query-order-list` is absent from the public documentation and failed every testnet request attempted during review. -- Remove `AssetService::coinConvertLimitQuery()` and `AssetService::limitOrderCallback()` because their endpoints are absent from the public documentation. Although the convert-limit endpoint currently responds on testnet, an official SDK should not promise an unsupported public contract. -- Remove `AssetService::assetInfoQuery()` and `AssetService::transferSubMemberSave()` because their documentation lives under the official `abandon` section. They are new, unreleased additions here, so removal does not break a released PHP API. -- Change `AccountService::getTradeInfoForAnalysis()` to require `string $symbol` and merge it into the signed query. -- Change `SpotMarginService::queryFixedBorrowMarket()` to require only `string $orderCurrency`; callers may pass optional `orderBy` through `$options`. - -## Documentation - -- Remove deleted methods from the `0.1.1` changelog entry. -- Update every newly added `@see` URL to the canonical public documentation route rather than assuming the endpoint path is also the documentation path. -- Keep the version bump and all other endpoint additions unchanged. - -## Tests - -- Add focused request-contract tests that assert the corrected method signatures, HTTP methods, paths, and serialized parameters. -- Add an inventory regression test asserting that the five removed methods are not part of the public service API. -- Run the full PHPUnit suite, PHPStan, PHP CS Fixer dry-run, syntax checks, and `git diff --check`. -- Re-run the corrected read-only methods against testnet. Do not run asset-moving or account-setting POST endpoints. - -## Compatibility and error handling - -All affected methods are unreleased working-tree additions, so correcting or removing them before release is preferable to carrying compatibility shims. Existing exception and response behavior remains unchanged.