@upshiftfinance/sdk 0.0.0-stage → 0.1.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 +21 -0
- package/README.md +408 -2
- package/lib/abis/AddressResolver.d.ts +28 -0
- package/lib/abis/AddressResolver.js +23 -0
- package/lib/abis/ChainlinkV3.d.ts +87 -0
- package/lib/abis/ChainlinkV3.js +117 -0
- package/lib/abis/ERC20.d.ts +168 -0
- package/lib/abis/ERC20.js +226 -0
- package/lib/abis/ERC20_Bytes32.d.ts +139 -0
- package/lib/abis/ERC20_Bytes32.js +196 -0
- package/lib/abis/ERC4626.d.ts +364 -0
- package/lib/abis/ERC4626.js +507 -0
- package/lib/abis/ERC721.d.ts +231 -0
- package/lib/abis/ERC721.js +321 -0
- package/lib/abis/FeeOracle.d.ts +120 -0
- package/lib/abis/FeeOracle.js +162 -0
- package/lib/abis/LendingPool.d.ts +1393 -0
- package/lib/abis/LendingPool.js +1807 -0
- package/lib/abis/LendingPoolV2.d.ts +1413 -0
- package/lib/abis/LendingPoolV2.js +1833 -0
- package/lib/abis/LendingPoolV3.d.ts +1677 -0
- package/lib/abis/LendingPoolV3.js +1160 -0
- package/lib/abis/Loan.d.ts +837 -0
- package/lib/abis/Loan.js +1080 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.d.ts +137 -0
- package/lib/abis/MultiAssetNativeDepositWrapper.js +125 -0
- package/lib/abis/Multicall3.d.ts +30 -0
- package/lib/abis/Multicall3.js +97 -0
- package/lib/abis/OFT.d.ts +116 -0
- package/lib/abis/OFT.js +85 -0
- package/lib/abis/PoolAdapter.d.ts +36 -0
- package/lib/abis/PoolAdapter.js +51 -0
- package/lib/abis/RewardDistributor.d.ts +267 -0
- package/lib/abis/RewardDistributor.js +352 -0
- package/lib/abis/RwaRedeemSubaccount.d.ts +747 -0
- package/lib/abis/RwaRedeemSubaccount.js +548 -0
- package/lib/abis/SmartAccount.d.ts +17 -0
- package/lib/abis/SmartAccount.js +19 -0
- package/lib/abis/SwapRouter.d.ts +953 -0
- package/lib/abis/SwapRouter.js +1228 -0
- package/lib/abis/TextResolver.d.ts +16 -0
- package/lib/abis/TextResolver.js +16 -0
- package/lib/abis/TokenizedVaultV2.d.ts +1364 -0
- package/lib/abis/TokenizedVaultV2.js +1041 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.d.ts +1456 -0
- package/lib/abis/TokenizedVaultV2DepositWithPermit.js +1878 -0
- package/lib/abis/TokenizedVaultV2Receipt.d.ts +1568 -0
- package/lib/abis/TokenizedVaultV2Receipt.js +1061 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.d.ts +454 -0
- package/lib/abis/TokenizedVaultV2SenderAllocationWhitelist.js +327 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.d.ts +1466 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAllocation.js +1092 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.d.ts +274 -0
- package/lib/abis/TokenizedVaultV2WhitelistedAssets.js +167 -0
- package/lib/abis/UniversalResolverResolve.d.ts +69 -0
- package/lib/abis/UniversalResolverResolve.js +35 -0
- package/lib/abis/UniversalSignatureValidator.d.ts +17 -0
- package/lib/abis/UniversalSignatureValidator.js +30 -0
- package/lib/abis/WrapperAdapter.d.ts +71 -0
- package/lib/abis/WrapperAdapter.js +77 -0
- package/lib/abis/index.d.ts +34 -0
- package/lib/abis/index.js +51 -0
- package/lib/adapters/evm/getters.d.ts +19 -0
- package/lib/adapters/evm/getters.js +249 -0
- package/lib/adapters/evm/index.d.ts +539 -0
- package/lib/adapters/evm/index.js +656 -0
- package/lib/adapters/evm/utils.d.ts +8 -0
- package/lib/adapters/evm/utils.js +51 -0
- package/lib/adapters/solana/confirm.d.ts +88 -0
- package/lib/adapters/solana/confirm.js +291 -0
- package/lib/adapters/solana/constants.d.ts +42 -0
- package/lib/adapters/solana/constants.js +59 -0
- package/lib/adapters/solana/getters.d.ts +42 -0
- package/lib/adapters/solana/getters.js +275 -0
- package/lib/adapters/solana/idl/vault-idl.d.ts +700 -0
- package/lib/adapters/solana/idl/vault-idl.js +2101 -0
- package/lib/adapters/solana/idl/withdrawal-queue-idl.d.ts +795 -0
- package/lib/adapters/solana/idl/withdrawal-queue-idl.js +1864 -0
- package/lib/adapters/solana/index.d.ts +372 -0
- package/lib/adapters/solana/index.js +459 -0
- package/lib/adapters/solana/pricing.d.ts +184 -0
- package/lib/adapters/solana/pricing.js +239 -0
- package/lib/adapters/solana/queue-hints.d.ts +29 -0
- package/lib/adapters/solana/queue-hints.js +59 -0
- package/lib/adapters/solana/queue.actions.d.ts +97 -0
- package/lib/adapters/solana/queue.actions.js +468 -0
- package/lib/adapters/solana/token-reads.d.ts +108 -0
- package/lib/adapters/solana/token-reads.js +145 -0
- package/lib/adapters/solana/types.d.ts +325 -0
- package/lib/adapters/solana/types.js +3 -0
- package/lib/adapters/solana/utils.d.ts +229 -0
- package/lib/adapters/solana/utils.js +773 -0
- package/lib/adapters/solana/vault.actions.d.ts +140 -0
- package/lib/adapters/solana/vault.actions.js +657 -0
- package/lib/adapters/solana/withdrawal-queue.d.ts +125 -0
- package/lib/adapters/solana/withdrawal-queue.js +301 -0
- package/lib/adapters/stellar/actions.d.ts +41 -0
- package/lib/adapters/stellar/actions.js +126 -0
- package/lib/adapters/stellar/constants.d.ts +43 -0
- package/lib/adapters/stellar/constants.js +53 -0
- package/lib/adapters/stellar/getters.d.ts +68 -0
- package/lib/adapters/stellar/getters.js +290 -0
- package/lib/adapters/stellar/index.d.ts +126 -0
- package/lib/adapters/stellar/index.js +187 -0
- package/lib/adapters/stellar/invocation.d.ts +55 -0
- package/lib/adapters/stellar/invocation.js +92 -0
- package/lib/adapters/stellar/soroban.d.ts +131 -0
- package/lib/adapters/stellar/soroban.js +617 -0
- package/lib/adapters/stellar/submit.d.ts +42 -0
- package/lib/adapters/stellar/submit.js +195 -0
- package/lib/adapters/stellar/types.d.ts +57 -0
- package/lib/adapters/stellar/types.js +6 -0
- package/lib/adapters/stellar/utils.d.ts +24 -0
- package/lib/adapters/stellar/utils.js +34 -0
- package/lib/adapters/sui/constants.d.ts +1 -0
- package/lib/adapters/sui/constants.js +9 -0
- package/lib/adapters/sui/getters.d.ts +24 -0
- package/lib/adapters/sui/getters.js +134 -0
- package/lib/adapters/sui/index.d.ts +53 -0
- package/lib/adapters/sui/index.js +96 -0
- package/lib/adapters/sui/transformer.d.ts +10 -0
- package/lib/adapters/sui/transformer.js +115 -0
- package/lib/adapters/sui/types.d.ts +70 -0
- package/lib/adapters/sui/types.js +3 -0
- package/lib/adapters/sui/utils.d.ts +8 -0
- package/lib/adapters/sui/utils.js +17 -0
- package/lib/core/analytics/app-name.d.ts +27 -0
- package/lib/core/analytics/app-name.js +48 -0
- package/lib/core/analytics/chain-name.d.ts +9 -0
- package/lib/core/analytics/chain-name.js +34 -0
- package/lib/core/analytics/constants.d.ts +15 -0
- package/lib/core/analytics/constants.js +28 -0
- package/lib/core/analytics/env.d.ts +46 -0
- package/lib/core/analytics/env.js +147 -0
- package/lib/core/analytics/index.d.ts +39 -0
- package/lib/core/analytics/index.js +83 -0
- package/lib/core/analytics/instrumentation.d.ts +29 -0
- package/lib/core/analytics/instrumentation.js +292 -0
- package/lib/core/analytics/method-taxonomy.d.ts +19 -0
- package/lib/core/analytics/method-taxonomy.js +156 -0
- package/lib/core/analytics/metrics.d.ts +48 -0
- package/lib/core/analytics/metrics.js +142 -0
- package/lib/core/analytics/sanitize.d.ts +57 -0
- package/lib/core/analytics/sanitize.js +272 -0
- package/lib/core/analytics/sentry-runtime.d.ts +15 -0
- package/lib/core/analytics/sentry-runtime.js +131 -0
- package/lib/core/analytics/sentry.d.ts +100 -0
- package/lib/core/analytics/sentry.js +696 -0
- package/lib/core/analytics/types.d.ts +55 -0
- package/lib/core/analytics/types.js +3 -0
- package/lib/core/analytics/user-identity.d.ts +55 -0
- package/lib/core/analytics/user-identity.js +218 -0
- package/lib/core/analytics/version.d.ts +6 -0
- package/lib/core/analytics/version.js +10 -0
- package/lib/core/attribution.d.ts +159 -0
- package/lib/core/attribution.js +194 -0
- package/lib/core/auth/index.d.ts +1 -0
- package/lib/core/auth/index.js +18 -0
- package/lib/core/auth/verify.d.ts +2 -0
- package/lib/core/auth/verify.js +35 -0
- package/lib/core/base.class.d.ts +193 -0
- package/lib/core/base.class.js +163 -0
- package/lib/core/cache.d.ts +9 -0
- package/lib/core/cache.js +31 -0
- package/lib/core/constants/adapters.d.ts +103 -0
- package/lib/core/constants/adapters.js +180 -0
- package/lib/core/constants/core.d.ts +162 -0
- package/lib/core/constants/core.js +281 -0
- package/lib/core/constants/swap-router.d.ts +180 -0
- package/lib/core/constants/swap-router.js +203 -0
- package/lib/core/constants/vaults.d.ts +93 -0
- package/lib/core/constants/vaults.js +277 -0
- package/lib/core/constants/web3.d.ts +106 -0
- package/lib/core/constants/web3.js +251 -0
- package/lib/core/errors/index.d.ts +177 -0
- package/lib/core/errors/index.js +257 -0
- package/lib/core/fetcher.d.ts +237 -0
- package/lib/core/fetcher.js +1103 -0
- package/lib/core/helpers/adapters.d.ts +13 -0
- package/lib/core/helpers/adapters.js +39 -0
- package/lib/core/helpers/chain-address.d.ts +13 -0
- package/lib/core/helpers/chain-address.js +47 -0
- package/lib/core/helpers/chain-error.d.ts +207 -0
- package/lib/core/helpers/chain-error.js +697 -0
- package/lib/core/helpers/chain-support.d.ts +98 -0
- package/lib/core/helpers/chain-support.js +139 -0
- package/lib/core/helpers/concurrency.d.ts +51 -0
- package/lib/core/helpers/concurrency.js +79 -0
- package/lib/core/helpers/core.d.ts +92 -0
- package/lib/core/helpers/core.js +368 -0
- package/lib/core/helpers/explorer-link.d.ts +16 -0
- package/lib/core/helpers/explorer-link.js +26 -0
- package/lib/core/helpers/multicall.d.ts +68 -0
- package/lib/core/helpers/multicall.js +103 -0
- package/lib/core/helpers/revert-decode.d.ts +248 -0
- package/lib/core/helpers/revert-decode.js +515 -0
- package/lib/core/helpers/signer.d.ts +61 -0
- package/lib/core/helpers/signer.js +184 -0
- package/lib/core/helpers/swap-router.d.ts +269 -0
- package/lib/core/helpers/swap-router.js +542 -0
- package/lib/core/helpers/vault-version.d.ts +24 -0
- package/lib/core/helpers/vault-version.js +83 -0
- package/lib/core/helpers/vaults.d.ts +89 -0
- package/lib/core/helpers/vaults.js +241 -0
- package/lib/core/helpers/web3.d.ts +366 -0
- package/lib/core/helpers/web3.js +1034 -0
- package/lib/core/index.d.ts +23 -0
- package/lib/core/index.js +40 -0
- package/lib/core/logger/curator-alert.d.ts +217 -0
- package/lib/core/logger/curator-alert.js +276 -0
- package/lib/core/logger/index.d.ts +99 -0
- package/lib/core/logger/index.js +163 -0
- package/lib/core/logger/slack.d.ts +49 -0
- package/lib/core/logger/slack.js +111 -0
- package/lib/core/vault-metadata.d.ts +12 -0
- package/lib/core/vault-metadata.js +42 -0
- package/lib/core/version-check.d.ts +58 -0
- package/lib/core/version-check.js +182 -0
- package/lib/evm/index.d.ts +2 -0
- package/lib/evm/index.js +19 -0
- package/lib/evm/methods/crossChainVault.d.ts +132 -0
- package/lib/evm/methods/crossChainVault.js +857 -0
- package/lib/evm/methods/crossChainVaultRegistry.d.ts +92 -0
- package/lib/evm/methods/crossChainVaultRegistry.js +239 -0
- package/lib/evm/methods/index.d.ts +2 -0
- package/lib/evm/methods/index.js +19 -0
- package/lib/evm/types/crossChain.d.ts +363 -0
- package/lib/evm/types/crossChain.js +20 -0
- package/lib/evm/types/index.d.ts +1 -0
- package/lib/evm/types/index.js +18 -0
- package/lib/index.d.ts +30 -0
- package/lib/index.js +52 -0
- package/lib/main.d.ts +596 -0
- package/lib/main.js +681 -0
- package/lib/modules/api/fetcher.d.ts +108 -0
- package/lib/modules/api/fetcher.js +187 -0
- package/lib/modules/api/index.d.ts +1 -0
- package/lib/modules/api/index.js +6 -0
- package/lib/modules/api/main.d.ts +587 -0
- package/lib/modules/api/main.js +911 -0
- package/lib/modules/sub-accounts/fetcher.d.ts +53 -0
- package/lib/modules/sub-accounts/fetcher.js +96 -0
- package/lib/modules/sub-accounts/index.d.ts +2 -0
- package/lib/modules/sub-accounts/index.js +19 -0
- package/lib/modules/sub-accounts/main.d.ts +249 -0
- package/lib/modules/sub-accounts/main.js +211 -0
- package/lib/modules/sub-accounts/utils.d.ts +106 -0
- package/lib/modules/sub-accounts/utils.js +112 -0
- package/lib/modules/vaults/adapter.helpers.d.ts +84 -0
- package/lib/modules/vaults/adapter.helpers.js +202 -0
- package/lib/modules/vaults/fetcher.d.ts +147 -0
- package/lib/modules/vaults/fetcher.js +357 -0
- package/lib/modules/vaults/getters.d.ts +1060 -0
- package/lib/modules/vaults/getters.js +4079 -0
- package/lib/modules/vaults/index.d.ts +20 -0
- package/lib/modules/vaults/index.js +44 -0
- package/lib/modules/vaults/main.d.ts +607 -0
- package/lib/modules/vaults/main.js +1687 -0
- package/lib/modules/vaults/prefetch.d.ts +65 -0
- package/lib/modules/vaults/prefetch.js +120 -0
- package/lib/modules/vaults/read.actions.d.ts +406 -0
- package/lib/modules/vaults/read.actions.js +891 -0
- package/lib/modules/vaults/types.d.ts +149 -0
- package/lib/modules/vaults/types.js +3 -0
- package/lib/modules/vaults/utils/call-data-decoder.d.ts +61 -0
- package/lib/modules/vaults/utils/call-data-decoder.js +194 -0
- package/lib/modules/vaults/utils/date-utils.d.ts +50 -0
- package/lib/modules/vaults/utils/date-utils.js +84 -0
- package/lib/modules/vaults/utils.d.ts +153 -0
- package/lib/modules/vaults/utils.js +818 -0
- package/lib/modules/vaults/write.actions.d.ts +812 -0
- package/lib/modules/vaults/write.actions.js +2377 -0
- package/lib/polyfills.d.ts +1 -0
- package/lib/polyfills.js +12 -0
- package/lib/sdk.d.ts +30154 -0
- package/lib/services/coingecko/fetcher.d.ts +15 -0
- package/lib/services/coingecko/fetcher.js +67 -0
- package/lib/services/coingecko/index.d.ts +2 -0
- package/lib/services/coingecko/index.js +19 -0
- package/lib/services/coingecko/utils.d.ts +1 -0
- package/lib/services/coingecko/utils.js +24 -0
- package/lib/services/debank/fetcher.d.ts +126 -0
- package/lib/services/debank/fetcher.js +47 -0
- package/lib/services/debank/index.d.ts +2 -0
- package/lib/services/debank/index.js +19 -0
- package/lib/services/debank/utils.d.ts +50 -0
- package/lib/services/debank/utils.js +325 -0
- package/lib/services/layerzero/deposits.d.ts +55 -0
- package/lib/services/layerzero/deposits.js +174 -0
- package/lib/services/layerzero/redeems.d.ts +20 -0
- package/lib/services/layerzero/redeems.js +92 -0
- package/lib/services/layerzero/utils.d.ts +9 -0
- package/lib/services/layerzero/utils.js +22 -0
- package/lib/services/octavfi/fetcher.d.ts +33 -0
- package/lib/services/octavfi/fetcher.js +39 -0
- package/lib/services/octavfi/index.d.ts +3 -0
- package/lib/services/octavfi/index.js +20 -0
- package/lib/services/octavfi/types.d.ts +34 -0
- package/lib/services/octavfi/types.js +3 -0
- package/lib/services/octavfi/utils.d.ts +16 -0
- package/lib/services/octavfi/utils.js +244 -0
- package/lib/services/subgraph/fetcher.d.ts +2 -0
- package/lib/services/subgraph/fetcher.js +66 -0
- package/lib/services/subgraph/index.d.ts +2 -0
- package/lib/services/subgraph/index.js +19 -0
- package/lib/services/subgraph/schema.d.ts +48 -0
- package/lib/services/subgraph/schema.js +87 -0
- package/lib/services/subgraph/vaults.d.ts +83 -0
- package/lib/services/subgraph/vaults.js +1282 -0
- package/lib/services/swap-quotes/index.d.ts +105 -0
- package/lib/services/swap-quotes/index.js +77 -0
- package/lib/services/swap-quotes/paraswap.d.ts +51 -0
- package/lib/services/swap-quotes/paraswap.js +138 -0
- package/lib/services/untangled/fetcher.d.ts +40 -0
- package/lib/services/untangled/fetcher.js +110 -0
- package/lib/services/untangled/index.d.ts +3 -0
- package/lib/services/untangled/index.js +20 -0
- package/lib/services/untangled/types.d.ts +83 -0
- package/lib/services/untangled/types.js +10 -0
- package/lib/services/untangled/utils.d.ts +91 -0
- package/lib/services/untangled/utils.js +339 -0
- package/lib/types/api.d.ts +498 -0
- package/lib/types/api.js +3 -0
- package/lib/types/index.d.ts +12 -0
- package/lib/types/index.js +28 -0
- package/lib/types/points.d.ts +28 -0
- package/lib/types/points.js +3 -0
- package/lib/types/pools.d.ts +144 -0
- package/lib/types/pools.js +3 -0
- package/lib/types/staking.d.ts +28 -0
- package/lib/types/staking.js +3 -0
- package/lib/types/sub-accounts.d.ts +150 -0
- package/lib/types/sub-accounts.js +3 -0
- package/lib/types/subgraph.d.ts +84 -0
- package/lib/types/subgraph.js +3 -0
- package/lib/types/typed-contract.d.ts +102 -0
- package/lib/types/typed-contract.js +3 -0
- package/lib/types/user.d.ts +1 -0
- package/lib/types/user.js +3 -0
- package/lib/types/vaults.d.ts +886 -0
- package/lib/types/vaults.js +30 -0
- package/lib/types/web3.d.ts +81 -0
- package/lib/types/web3.js +14 -0
- package/lib/types/webserver.d.ts +730 -0
- package/lib/types/webserver.js +3 -0
- package/package.json +78 -3
|
@@ -0,0 +1,911 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UpshiftApi = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* The Upshift backend API Module — read-only client for public backend
|
|
6
|
+
* endpoints (transparency dashboard, unrealized PnL) and authenticated
|
|
7
|
+
* loan-book / risk / OTC reads. Accessible as `sdk.apiModule`.
|
|
8
|
+
*
|
|
9
|
+
* @module UpshiftApi
|
|
10
|
+
*/
|
|
11
|
+
const ethers_1 = require("ethers");
|
|
12
|
+
const fetcher_1 = require("./fetcher");
|
|
13
|
+
const base_class_1 = require("../../core/base.class");
|
|
14
|
+
const core_1 = require("../../core/constants/core");
|
|
15
|
+
const errors_1 = require("../../core/errors");
|
|
16
|
+
const fetcher_2 = require("../../core/fetcher");
|
|
17
|
+
const chain_address_1 = require("../../core/helpers/chain-address");
|
|
18
|
+
function toUnrealizedPnlSnapshot(raw) {
|
|
19
|
+
return {
|
|
20
|
+
timestamp: raw.timestamp,
|
|
21
|
+
vaultName: raw.vault_name,
|
|
22
|
+
vaultAddress: raw.vault_address,
|
|
23
|
+
strategistName: raw.strategist_name ?? null,
|
|
24
|
+
referenceAsset: raw.reference_asset,
|
|
25
|
+
assetPrice: raw.asset_price,
|
|
26
|
+
tvlOnVault: raw.tvl_on_vault,
|
|
27
|
+
currentRedeemRatio: raw.current_redeem_ratio,
|
|
28
|
+
actualTvl: raw.actual_tvl,
|
|
29
|
+
adjustedRedeemRatio: raw.adjusted_redeem_ratio,
|
|
30
|
+
unrealizedPnl: raw.unrealized_pnl,
|
|
31
|
+
unrealizedPnlInAsset: raw.unrealized_pnl_in_asset,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function assertVaultAddress(vault, method) {
|
|
35
|
+
const valid = typeof vault === 'string' &&
|
|
36
|
+
vault.length > 0 &&
|
|
37
|
+
((0, ethers_1.isAddress)(vault) ||
|
|
38
|
+
(0, chain_address_1.isSolanaAddress)(vault) ||
|
|
39
|
+
(0, chain_address_1.isStellarAddress)(vault) ||
|
|
40
|
+
(0, chain_address_1.isSuiAddress)(vault));
|
|
41
|
+
if (!valid) {
|
|
42
|
+
throw new errors_1.UpshiftValidationError('INVALID_ADDRESS', `${method}: "${vault}" is not a valid vault address — pass the vault's EVM (0x…), Solana, Stellar, or Sui (0x… 64 hex chars) address.`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** Transparency endpoints are EVM-only and require a positive integer chain id. */
|
|
46
|
+
function assertTransparencyArgs(method, vault, chainId) {
|
|
47
|
+
if (!(0, ethers_1.isAddress)(vault)) {
|
|
48
|
+
throw new errors_1.UpshiftValidationError('INVALID_ADDRESS', `${method}: vault must be an EVM address (transparency endpoints are EVM-only), got ${String(vault)}.`);
|
|
49
|
+
}
|
|
50
|
+
if (!Number.isInteger(chainId) || chainId <= 0) {
|
|
51
|
+
throw new errors_1.UpshiftValidationError('INVALID_CHAIN', `${method}: chainId must be a positive integer EVM chain id, got ${chainId}. Transparency endpoints are EVM-only.`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
55
|
+
/** Date-window params are plain `YYYY-MM-DD` strings; anything else is rejected before the request. */
|
|
56
|
+
function assertIsoDate(method, name, value) {
|
|
57
|
+
if (value !== undefined && !ISO_DATE.test(value)) {
|
|
58
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: ${name} must be YYYY-MM-DD, got "${value}".`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Cheap contract-drift guard for the chain-scoped transparency responses.
|
|
63
|
+
* Every one of them (`positions`, `historical_allocations`, `fees`,
|
|
64
|
+
* `governance/*`) is an object keyed by `vault_address` + `chain_id`; if the
|
|
65
|
+
* body is not that, the backend contract has changed and partner code must
|
|
66
|
+
* not receive a silently-malformed object. Leaves are deliberately NOT
|
|
67
|
+
* validated — full validation of eight nested shapes is not worth the
|
|
68
|
+
* weight, and the top-level check catches the common drift (envelope
|
|
69
|
+
* wrapping, error-object-over-200, renamed root).
|
|
70
|
+
*/
|
|
71
|
+
function assertTransparencyEnvelope(data, method) {
|
|
72
|
+
const valid = data !== null &&
|
|
73
|
+
typeof data === 'object' &&
|
|
74
|
+
!Array.isArray(data) &&
|
|
75
|
+
typeof data.vault_address === 'string' &&
|
|
76
|
+
typeof data.chain_id === 'number';
|
|
77
|
+
if (!valid) {
|
|
78
|
+
throw new errors_1.UpshiftServerError(200, `${method}: unexpected response shape from the Upshift API — expected an object with vault_address and chain_id. The backend contract may have changed; refresh packages/sdk/api-spec and update the SDK.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Same guard for the backing-series endpoint, whose body is a bare array of
|
|
83
|
+
* ratio points (no envelope). Anything else is contract drift.
|
|
84
|
+
*/
|
|
85
|
+
function assertTransparencyArray(data, method) {
|
|
86
|
+
if (!Array.isArray(data)) {
|
|
87
|
+
throw new errors_1.UpshiftServerError(200, `${method}: unexpected response shape from the Upshift API — expected an array of ratio points. The backend contract may have changed; refresh packages/sdk/api-spec and update the SDK.`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/** Runtime mirror of {@link ITransparencyTimelockStatus} (+ `'all'`) — plain-JS callers bypass the type. */
|
|
91
|
+
const TRANSPARENCY_TIMELOCK_STATUSES = [
|
|
92
|
+
'scheduled',
|
|
93
|
+
'executed',
|
|
94
|
+
'cancelled',
|
|
95
|
+
'all',
|
|
96
|
+
];
|
|
97
|
+
/** Runtime mirror of {@link ITransparencyAuditCategory} — plain-JS callers bypass the type. */
|
|
98
|
+
const TRANSPARENCY_AUDIT_CATEGORIES = [
|
|
99
|
+
'Strategy',
|
|
100
|
+
'Role',
|
|
101
|
+
'Permission',
|
|
102
|
+
'Attestation',
|
|
103
|
+
];
|
|
104
|
+
/** Rejects a filter value outside its allowlist before any request is made (types only guard TS callers). */
|
|
105
|
+
function assertOneOf(method, name, value, allowed) {
|
|
106
|
+
if (value !== undefined && !allowed.includes(value)) {
|
|
107
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: ${name} must be one of ${allowed.map((v) => `'${v}'`).join(', ')}, got "${String(value)}".`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function assertAddressArg(value, label, method) {
|
|
111
|
+
const valid = typeof value === 'string' &&
|
|
112
|
+
value.length > 0 &&
|
|
113
|
+
((0, ethers_1.isAddress)(value) ||
|
|
114
|
+
(0, chain_address_1.isSolanaAddress)(value) ||
|
|
115
|
+
(0, chain_address_1.isStellarAddress)(value) ||
|
|
116
|
+
(0, chain_address_1.isSuiAddress)(value));
|
|
117
|
+
if (!valid) {
|
|
118
|
+
throw new errors_1.UpshiftValidationError('INVALID_ADDRESS', `${method}: "${value}" is not a valid ${label} — pass an EVM (0x…), Solana, Stellar, or Sui (0x… 64 hex chars) address.`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
const SNAPSHOT_STRING_FIELDS = [
|
|
122
|
+
'timestamp',
|
|
123
|
+
'vault_name',
|
|
124
|
+
'vault_address',
|
|
125
|
+
'reference_asset',
|
|
126
|
+
];
|
|
127
|
+
const SNAPSHOT_NUMBER_FIELDS = [
|
|
128
|
+
'asset_price',
|
|
129
|
+
'tvl_on_vault',
|
|
130
|
+
'current_redeem_ratio',
|
|
131
|
+
'actual_tvl',
|
|
132
|
+
'adjusted_redeem_ratio',
|
|
133
|
+
'unrealized_pnl',
|
|
134
|
+
'unrealized_pnl_in_asset',
|
|
135
|
+
];
|
|
136
|
+
function isRawSnapshot(item) {
|
|
137
|
+
if (!item || typeof item !== 'object')
|
|
138
|
+
return false;
|
|
139
|
+
const record = item;
|
|
140
|
+
return (SNAPSHOT_STRING_FIELDS.every((field) => typeof record[field] === 'string') &&
|
|
141
|
+
SNAPSHOT_NUMBER_FIELDS.every((field) => typeof record[field] === 'number'));
|
|
142
|
+
}
|
|
143
|
+
function assertSnapshotArray(data, method) {
|
|
144
|
+
const valid = Array.isArray(data) && data.every(isRawSnapshot);
|
|
145
|
+
if (!valid) {
|
|
146
|
+
throw new errors_1.UpshiftServerError(200, `${method}: unexpected response shape from the Upshift API — expected an array of PnL snapshots. The backend contract may have changed; refresh packages/sdk/api-spec and update the SDK.`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Read-only client for Upshift backend REST endpoints that have no on-chain
|
|
151
|
+
* equivalent: the unrealized-PnL series, the transparency dashboard
|
|
152
|
+
* (position snapshot, backing series, smoothed APY, allocations, fee config,
|
|
153
|
+
* governance), plus authenticated loan-book / risk / OTC reads.
|
|
154
|
+
*
|
|
155
|
+
* Every public method makes exactly one HTTPS request to the Upshift API and
|
|
156
|
+
* zero RPC calls. Responses are not cached by the SDK: this is time-sensitive
|
|
157
|
+
* state where staleness is worse than a request. Accessible as
|
|
158
|
+
* `sdk.apiModule`; only the unrealized-PnL methods are also mirrored on the
|
|
159
|
+
* root `UpshiftSDK` class.
|
|
160
|
+
*/
|
|
161
|
+
class UpshiftApi extends base_class_1.UpshiftBase {
|
|
162
|
+
headers = null;
|
|
163
|
+
constructor(baseConfig) {
|
|
164
|
+
super(baseConfig);
|
|
165
|
+
this.headers = {
|
|
166
|
+
'x-environment': this.monitoring?.['x-environment'],
|
|
167
|
+
'x-user-id': this.monitoring?.['x-user-id'],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Retrieve the global loan-book aggregate across every active client
|
|
172
|
+
* subaccount — one {@link ILoanBookInfo} entry per loan, with principal /
|
|
173
|
+
* interest amounts, APRs, state, and the next upcoming payment.
|
|
174
|
+
*
|
|
175
|
+
* Backed by the admin-only `GET /dashboard/loans` backend endpoint (60-second
|
|
176
|
+
* server-side cache), so the Upshift API key configured on the SDK must
|
|
177
|
+
* belong to an admin user. Makes exactly one HTTP request and no RPC calls.
|
|
178
|
+
*
|
|
179
|
+
* @returns Array of loan-book entries; empty when there are no active loans.
|
|
180
|
+
* @throws UpshiftAuthError When the API key is missing or not admin-scoped.
|
|
181
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status.
|
|
182
|
+
* @example
|
|
183
|
+
* const loans = await sdk.apiModule.getDashboardLoans();
|
|
184
|
+
* const active = loans.filter((l) => l.state === 'ACTIVE');
|
|
185
|
+
*/
|
|
186
|
+
async getDashboardLoans() {
|
|
187
|
+
return (0, fetcher_1.fetchDashboardLoans)(this.keys.upshift, this.headers ?? undefined);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Retrieve every token discount-factor ladder the risk engine applies when
|
|
191
|
+
* valuing collateral.
|
|
192
|
+
*
|
|
193
|
+
* Backed by `GET /risk/discount_factors` (60-second server-side cache),
|
|
194
|
+
* which requires an authenticated Upshift user; an admin-scoped API key
|
|
195
|
+
* works. Makes exactly one HTTP request and no RPC calls.
|
|
196
|
+
*
|
|
197
|
+
* @returns Array of {@link IDiscountFactorLadder}, one per whitelisted token that has a configured ladder.
|
|
198
|
+
* @throws UpshiftAuthError When the API key is missing or not authorized.
|
|
199
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status.
|
|
200
|
+
* @example
|
|
201
|
+
* const ladders = await sdk.apiModule.getDiscountFactors();
|
|
202
|
+
* console.log(ladders.map((d) => `${d.address}@${d.chain}`));
|
|
203
|
+
*/
|
|
204
|
+
async getDiscountFactors() {
|
|
205
|
+
return (0, fetcher_1.fetchDiscountFactors)(this.keys.upshift, this.headers ?? undefined);
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Compute how much collateral a subaccount has in excess of — or is short
|
|
209
|
+
* of — what it needs to hold a target health factor, for one collateral
|
|
210
|
+
* token.
|
|
211
|
+
*
|
|
212
|
+
* Backed by `GET /risk/collateral_excess_or_deficit` (60-second server-side
|
|
213
|
+
* cache), which resolves the subaccount and reads its current health factor.
|
|
214
|
+
* The backend serves this route to anonymous callers today, so no Upshift API
|
|
215
|
+
* key is needed; pass one if you get `AUTH_UNAUTHORIZED`. Makes exactly one
|
|
216
|
+
* HTTP request and no RPC calls.
|
|
217
|
+
*
|
|
218
|
+
* @param params.subaccount Subaccount (smart-contract wallet) address.
|
|
219
|
+
* @param params.tokenAddress Collateral token address to evaluate.
|
|
220
|
+
* @param params.tokenChain Numeric Upshift chain id of the token (e.g. `1` for Ethereum mainnet).
|
|
221
|
+
* @param params.targetHealthFactor Health factor to solve for. Defaults server-side to the minimum healthy factor (1.2); when supplied must be a finite number greater than 0.
|
|
222
|
+
* @returns The signed excess (positive) or deficit (negative) in USD and token units. Zeroes when the subaccount has no debt.
|
|
223
|
+
* @throws UpshiftValidationError When an address is invalid, `tokenChain` is not an integer, or `targetHealthFactor` is out of range.
|
|
224
|
+
* @throws UpshiftServerError When the token has no discount factor (backend 404) or the API otherwise responds non-2xx.
|
|
225
|
+
* @example
|
|
226
|
+
* const r = await sdk.apiModule.getCollateralExcessOrDeficit({
|
|
227
|
+
* subaccount: '0xabc…',
|
|
228
|
+
* tokenAddress: '0xdef…',
|
|
229
|
+
* tokenChain: 1,
|
|
230
|
+
* });
|
|
231
|
+
* console.log(r.amount_usd > 0 ? 'excess' : 'deficit');
|
|
232
|
+
*/
|
|
233
|
+
async getCollateralExcessOrDeficit(params) {
|
|
234
|
+
const method = 'getCollateralExcessOrDeficit';
|
|
235
|
+
assertAddressArg(params.subaccount, 'subaccount address', method);
|
|
236
|
+
assertAddressArg(params.tokenAddress, 'token address', method);
|
|
237
|
+
if (!Number.isInteger(params.tokenChain)) {
|
|
238
|
+
throw new errors_1.UpshiftValidationError('INVALID_CHAIN', `${method}: tokenChain must be an integer Upshift chain id, got ${params.tokenChain}.`);
|
|
239
|
+
}
|
|
240
|
+
if (params.targetHealthFactor !== undefined &&
|
|
241
|
+
(!Number.isFinite(params.targetHealthFactor) ||
|
|
242
|
+
params.targetHealthFactor <= 0)) {
|
|
243
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: targetHealthFactor must be a finite number greater than 0, got ${params.targetHealthFactor}.`);
|
|
244
|
+
}
|
|
245
|
+
return (0, fetcher_1.fetchCollateralExcessOrDeficit)(params, this.keys.upshift, this.headers ?? undefined);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Simulate the collateral required to open a hypothetical loan against a
|
|
249
|
+
* chosen basket of collateral tokens.
|
|
250
|
+
*
|
|
251
|
+
* This is a pure, read-only simulation: the backend `POST
|
|
252
|
+
* /risk/collateral_simulation` endpoint (60-second server-side cache)
|
|
253
|
+
* computes required collateral and effective discount factors and changes
|
|
254
|
+
* no state. The route is public, so no Upshift API key is needed. Makes
|
|
255
|
+
* exactly one HTTP request and no RPC calls.
|
|
256
|
+
*
|
|
257
|
+
* @param input Simulation parameters — see {@link ICollateralSimulationInput}. `collateral_tokens` and `collateral_token_allocation` must be non-empty and equal length; when `on_platform` is `true`, both `loan_redeployed_token_*` fields are required.
|
|
258
|
+
* @returns The simulated {@link ICollateralSimulationResults}: total debt, required collateral, resulting health factor, and a per-token breakdown.
|
|
259
|
+
* @throws UpshiftValidationError When addresses are invalid, `loan_amount` is not a finite non-negative number, the collateral arrays are empty / mismatched, or `on_platform` is set without redeployed-token details.
|
|
260
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status (e.g. a token missing a discount factor).
|
|
261
|
+
* @example
|
|
262
|
+
* const sim = await sdk.apiModule.simulateCollateral({
|
|
263
|
+
* loan_token_chain: 1,
|
|
264
|
+
* loan_token_address: '0xloan…',
|
|
265
|
+
* loan_amount: 1_000_000,
|
|
266
|
+
* collateral_tokens: [[1, '0xcol…']],
|
|
267
|
+
* collateral_token_allocation: [1],
|
|
268
|
+
* });
|
|
269
|
+
* console.log(sim.total_required_collateral_usd);
|
|
270
|
+
*/
|
|
271
|
+
async simulateCollateral(input) {
|
|
272
|
+
const method = 'simulateCollateral';
|
|
273
|
+
assertAddressArg(input.loan_token_address, 'loan token address', method);
|
|
274
|
+
if (!Number.isFinite(input.loan_amount) || input.loan_amount < 0) {
|
|
275
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: loan_amount must be a finite non-negative number, got ${input.loan_amount}.`);
|
|
276
|
+
}
|
|
277
|
+
if (!Array.isArray(input.collateral_tokens) ||
|
|
278
|
+
input.collateral_tokens.length === 0 ||
|
|
279
|
+
!Array.isArray(input.collateral_token_allocation) ||
|
|
280
|
+
input.collateral_token_allocation.length === 0) {
|
|
281
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: collateral_tokens and collateral_token_allocation must both be non-empty.`);
|
|
282
|
+
}
|
|
283
|
+
if (input.collateral_tokens.length !==
|
|
284
|
+
input.collateral_token_allocation.length) {
|
|
285
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: collateral_tokens (${input.collateral_tokens.length}) and collateral_token_allocation (${input.collateral_token_allocation.length}) must be the same length.`);
|
|
286
|
+
}
|
|
287
|
+
for (const [, address] of input.collateral_tokens) {
|
|
288
|
+
assertAddressArg(address, 'collateral token address', method);
|
|
289
|
+
}
|
|
290
|
+
if (input.on_platform &&
|
|
291
|
+
(input.loan_redeployed_token_chain === undefined ||
|
|
292
|
+
input.loan_redeployed_token_chain === null ||
|
|
293
|
+
!input.loan_redeployed_token_address)) {
|
|
294
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: on_platform requires both loan_redeployed_token_chain and loan_redeployed_token_address.`);
|
|
295
|
+
}
|
|
296
|
+
return (0, fetcher_1.fetchCollateralSimulation)(input, this.keys.upshift, this.headers ?? undefined);
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Fetch the decoded revert reason(s) for a transaction — error messages,
|
|
300
|
+
* revert strings, and recognized universal-subaccount errors extracted from
|
|
301
|
+
* a `debug_traceTransaction` call tree.
|
|
302
|
+
*
|
|
303
|
+
* Backed by the public (unauthenticated) `GET /revert_reason` endpoint; no
|
|
304
|
+
* API key required. The backend relies on the target chain's RPC supporting
|
|
305
|
+
* `debug_trace*`; on chains/RPCs without it the backend returns a 5xx whose
|
|
306
|
+
* detail explains why, surfaced here as an {@link UpshiftServerError}. Makes
|
|
307
|
+
* exactly one HTTP request and no RPC calls from the SDK itself.
|
|
308
|
+
*
|
|
309
|
+
* @param txHash Transaction hash to trace.
|
|
310
|
+
* @param chain Numeric Upshift chain id the transaction is on (e.g. `1` for Ethereum mainnet).
|
|
311
|
+
* @returns The decoded {@link IRevertReason}; all arrays empty when the trace yielded no matching signal.
|
|
312
|
+
* @throws UpshiftValidationError When `txHash` is empty or `chain` is not an integer.
|
|
313
|
+
* @throws UpshiftServerError When the chain/RPC does not support tracing, or the API otherwise responds non-2xx.
|
|
314
|
+
* @example
|
|
315
|
+
* const r = await sdk.apiModule.getRevertReason('0xabc…', 1);
|
|
316
|
+
* console.log(r.revert_reasons);
|
|
317
|
+
*/
|
|
318
|
+
async getRevertReason(txHash, chain) {
|
|
319
|
+
const method = 'getRevertReason';
|
|
320
|
+
if (typeof txHash !== 'string' || txHash.trim().length === 0) {
|
|
321
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: txHash must be a non-empty transaction hash.`);
|
|
322
|
+
}
|
|
323
|
+
if (!Number.isInteger(chain)) {
|
|
324
|
+
throw new errors_1.UpshiftValidationError('INVALID_CHAIN', `${method}: chain must be an integer Upshift chain id, got ${chain}.`);
|
|
325
|
+
}
|
|
326
|
+
return (0, fetcher_1.fetchRevertReason)(txHash, chain, this.headers ?? undefined);
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Retrieve every tracked OTC position.
|
|
330
|
+
*
|
|
331
|
+
* Backed by the admin-only `GET /otc/position` backend endpoint, so the
|
|
332
|
+
* configured Upshift API key must belong to an admin user. Makes exactly one
|
|
333
|
+
* HTTP request and no RPC calls.
|
|
334
|
+
*
|
|
335
|
+
* @returns Array of {@link IOtcPositionRead}; empty when there are no OTC positions.
|
|
336
|
+
* @throws UpshiftAuthError When the API key is missing or not admin-scoped.
|
|
337
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status.
|
|
338
|
+
* @example
|
|
339
|
+
* const positions = await sdk.apiModule.getOtcPositions();
|
|
340
|
+
*/
|
|
341
|
+
async getOtcPositions() {
|
|
342
|
+
return (0, fetcher_1.fetchOtcPositions)(this.keys.upshift, this.headers ?? undefined);
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Retrieve OTC margin requirements, optionally filtered by counterparty
|
|
346
|
+
* and/or payer.
|
|
347
|
+
*
|
|
348
|
+
* Backed by the admin-only `GET /otc/margin_requirement` backend endpoint,
|
|
349
|
+
* so the configured Upshift API key must belong to an admin user. Makes
|
|
350
|
+
* exactly one HTTP request and no RPC calls.
|
|
351
|
+
*
|
|
352
|
+
* @param options - Optional filters
|
|
353
|
+
* @param options.otcCounterpartyId - Restrict to a single counterparty (UUID)
|
|
354
|
+
* @param options.payer - Restrict to a single payer address
|
|
355
|
+
* @returns Array of {@link IOtcMarginRequirement} matching the filters (all when none given).
|
|
356
|
+
* @throws UpshiftAuthError When the API key is missing or not admin-scoped.
|
|
357
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status.
|
|
358
|
+
* @example
|
|
359
|
+
* const reqs = await sdk.apiModule.getOtcMarginRequirements({ payer: '0xabc…' });
|
|
360
|
+
*/
|
|
361
|
+
async getOtcMarginRequirements(options = {}) {
|
|
362
|
+
return (0, fetcher_1.fetchOtcMarginRequirements)(options, this.keys.upshift, this.headers ?? undefined);
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* List the subaccounts linked to a vault (curator surface).
|
|
366
|
+
*
|
|
367
|
+
* Backed by the curator-or-admin `GET
|
|
368
|
+
* /curator/vaults/{vault_address}/subaccounts` backend endpoint, so the
|
|
369
|
+
* configured Upshift API key must belong to the vault's curator or an admin.
|
|
370
|
+
* Makes exactly one HTTP request and no RPC calls.
|
|
371
|
+
*
|
|
372
|
+
* @param vaultAddress - The vault address (EVM `0x…`, Solana, or Stellar)
|
|
373
|
+
* @returns Array of subaccount records linked to the vault (same shape as the subaccount directory); empty when none are linked.
|
|
374
|
+
* @throws UpshiftValidationError When `vaultAddress` is not a valid address.
|
|
375
|
+
* @throws UpshiftAuthError When the API key is missing or not curator/admin for the vault.
|
|
376
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status.
|
|
377
|
+
* @example
|
|
378
|
+
* const subs = await sdk.apiModule.getCuratorVaultSubaccounts('0xvault…');
|
|
379
|
+
*/
|
|
380
|
+
async getCuratorVaultSubaccounts(vaultAddress) {
|
|
381
|
+
assertVaultAddress(vaultAddress, 'getCuratorVaultSubaccounts');
|
|
382
|
+
return (0, fetcher_1.fetchCuratorVaultSubaccounts)(vaultAddress, this.keys.upshift, this.headers ?? undefined);
|
|
383
|
+
}
|
|
384
|
+
/**
|
|
385
|
+
* Get on-chain whitelist status for every subaccount linked to a vault
|
|
386
|
+
* (curator surface).
|
|
387
|
+
*
|
|
388
|
+
* Backed by the curator-or-admin `GET
|
|
389
|
+
* /curator/vaults/{vault_address}/whitelist` backend endpoint. EVM vaults
|
|
390
|
+
* only — non-EVM vaults manage access internally and the backend returns a
|
|
391
|
+
* 400 (surfaced as {@link UpshiftServerError}). Makes exactly one HTTP
|
|
392
|
+
* request and no RPC calls from the SDK.
|
|
393
|
+
*
|
|
394
|
+
* @param vaultAddress - The EVM vault address (`0x…`)
|
|
395
|
+
* @returns Array of {@link ICuratorWhitelistStatus}, one per linked subaccount; empty when the vault has no subaccounts.
|
|
396
|
+
* @throws UpshiftValidationError When `vaultAddress` is not a valid address.
|
|
397
|
+
* @throws UpshiftAuthError When the API key is missing or not curator/admin for the vault.
|
|
398
|
+
* @throws UpshiftServerError When the vault is non-EVM (backend 400) or the API otherwise responds non-2xx.
|
|
399
|
+
* @example
|
|
400
|
+
* const status = await sdk.apiModule.getCuratorVaultWhitelist('0xvault…');
|
|
401
|
+
* console.log(status.filter((s) => !s.is_whitelisted));
|
|
402
|
+
*/
|
|
403
|
+
async getCuratorVaultWhitelist(vaultAddress) {
|
|
404
|
+
assertVaultAddress(vaultAddress, 'getCuratorVaultWhitelist');
|
|
405
|
+
return (0, fetcher_1.fetchCuratorVaultWhitelist)(vaultAddress, this.keys.upshift, this.headers ?? undefined);
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* List timelock (governance) requests for a vault on a chain, optionally
|
|
409
|
+
* filtered by status.
|
|
410
|
+
*
|
|
411
|
+
* Backed by the `GET /timelock-requests` backend endpoint. Makes exactly one
|
|
412
|
+
* HTTP request and no RPC calls.
|
|
413
|
+
*
|
|
414
|
+
* @param params.vaultAddress The vault address the requests target.
|
|
415
|
+
* @param params.chainId Numeric Upshift chain id (must be a positive integer).
|
|
416
|
+
* @param params.status Status filter: `"scheduled"` (backend default), `"executed"`, `"cancelled"`, or `"all"`. Omit to use the backend default.
|
|
417
|
+
* @returns Array of {@link ITimelockRequest}; empty when the vault has no matching requests.
|
|
418
|
+
* @throws UpshiftValidationError When `vaultAddress` is invalid or `chainId` is not a positive integer.
|
|
419
|
+
* @throws UpshiftServerError When the API responds with a non-2xx status (e.g. an invalid status filter).
|
|
420
|
+
* @example
|
|
421
|
+
* const reqs = await sdk.apiModule.getTimelockRequests({ vaultAddress: '0xvault…', chainId: 1 });
|
|
422
|
+
*/
|
|
423
|
+
async getTimelockRequests(params) {
|
|
424
|
+
const method = 'getTimelockRequests';
|
|
425
|
+
assertVaultAddress(params.vaultAddress, method);
|
|
426
|
+
if (!Number.isInteger(params.chainId) || params.chainId <= 0) {
|
|
427
|
+
throw new errors_1.UpshiftValidationError('INVALID_CHAIN', `${method}: chainId must be a positive integer Upshift chain id, got ${params.chainId}.`);
|
|
428
|
+
}
|
|
429
|
+
return (0, fetcher_1.fetchTimelockRequests)(params, this.keys.upshift, this.headers ?? undefined);
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Compute a vault's performance fees over a period (backend-computed from
|
|
433
|
+
* its snapshot history).
|
|
434
|
+
*
|
|
435
|
+
* Backed by `GET /metrics/vault_performance_fees`. The backend runs pandas
|
|
436
|
+
* over the vault's full snapshot history, so the first call is slow; results
|
|
437
|
+
* are cached server-side for 20 minutes. Makes exactly one HTTP request and
|
|
438
|
+
* no RPC calls.
|
|
439
|
+
*
|
|
440
|
+
* @param params.vault The vault address (EVM `0x…`, Solana, or Stellar).
|
|
441
|
+
* @param params.annualizedFeesPct Annualized performance-fee percentage. Defaults to 20.
|
|
442
|
+
* @param params.nativeDenominated Whether to denominate in the vault's native token. Defaults to `true`.
|
|
443
|
+
* @param params.calculationPeriod Period preset — `"YearToDate"` (default) or `"MonthToDate"`. Ignored by the backend when a custom `startDate`/`endDate` range is supplied.
|
|
444
|
+
* @param params.startDate ISO-8601 datetime range start. Must be supplied together with `endDate`.
|
|
445
|
+
* @param params.endDate ISO-8601 datetime range end. Must be supplied together with `startDate`.
|
|
446
|
+
* @returns The vault's {@link IVaultPerformanceFees} computation.
|
|
447
|
+
* @throws UpshiftValidationError When `vault` is invalid, or exactly one of `startDate`/`endDate` is supplied.
|
|
448
|
+
* @throws UpshiftServerError When there is insufficient snapshot data for the period, or the API otherwise responds non-2xx.
|
|
449
|
+
* @example
|
|
450
|
+
* const fees = await sdk.apiModule.getVaultPerformanceFees({ vault: '0xvault…' });
|
|
451
|
+
* console.log(fees.total_perf_fees_asset);
|
|
452
|
+
*/
|
|
453
|
+
async getVaultPerformanceFees(params) {
|
|
454
|
+
const method = 'getVaultPerformanceFees';
|
|
455
|
+
assertVaultAddress(params.vault, method);
|
|
456
|
+
const hasStart = params.startDate !== undefined;
|
|
457
|
+
const hasEnd = params.endDate !== undefined;
|
|
458
|
+
if (hasStart !== hasEnd) {
|
|
459
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: startDate and endDate must be supplied together (both or neither).`);
|
|
460
|
+
}
|
|
461
|
+
return (0, fetcher_1.fetchVaultPerformanceFees)({
|
|
462
|
+
vaultAddress: params.vault,
|
|
463
|
+
annualizedFeesPct: params.annualizedFeesPct ?? 20,
|
|
464
|
+
nativeDenominated: params.nativeDenominated ?? true,
|
|
465
|
+
calculationPeriod: params.calculationPeriod ?? 'YearToDate',
|
|
466
|
+
startDate: params.startDate,
|
|
467
|
+
endDate: params.endDate,
|
|
468
|
+
}, this.keys.upshift, this.headers ?? undefined);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Fetch a vault's NAV-oracle classification table — how each position/token
|
|
472
|
+
* is priced (Primary / Secondary Market / CeFi) and its USD value, plus
|
|
473
|
+
* warnings for tokens that could not be resolved.
|
|
474
|
+
*
|
|
475
|
+
* Backed by the public (unauthenticated) `GET
|
|
476
|
+
* /upshift/oracle_classification/{vault_address}` endpoint; no API key
|
|
477
|
+
* required. Reads the newest daily snapshot. Makes exactly one HTTP request
|
|
478
|
+
* and no RPC calls from the SDK.
|
|
479
|
+
*
|
|
480
|
+
* @param vault The vault address (EVM `0x…`, Solana, or Stellar).
|
|
481
|
+
* @param chainId Numeric Upshift chain id the vault lives on.
|
|
482
|
+
* @returns The vault's {@link IOracleClassification}.
|
|
483
|
+
* @throws UpshiftValidationError When `vault` is invalid or `chainId` is not an integer.
|
|
484
|
+
* @throws UpshiftServerError When the vault or its snapshot is not found, or the API otherwise responds non-2xx.
|
|
485
|
+
* @example
|
|
486
|
+
* const cls = await sdk.apiModule.getVaultOracleClassification('0xvault…', 1);
|
|
487
|
+
* console.log(cls.warnings);
|
|
488
|
+
*/
|
|
489
|
+
async getVaultOracleClassification(vault, chainId) {
|
|
490
|
+
const method = 'getVaultOracleClassification';
|
|
491
|
+
assertVaultAddress(vault, method);
|
|
492
|
+
if (!Number.isInteger(chainId)) {
|
|
493
|
+
throw new errors_1.UpshiftValidationError('INVALID_CHAIN', `${method}: chainId must be an integer Upshift chain id, got ${chainId}.`);
|
|
494
|
+
}
|
|
495
|
+
return (0, fetcher_1.fetchVaultOracleClassification)(vault, chainId, this.headers ?? undefined);
|
|
496
|
+
}
|
|
497
|
+
// -------------------------------------------------------------------------
|
|
498
|
+
// Transparency dashboard
|
|
499
|
+
//
|
|
500
|
+
// One method per card/tab of the Upshift per-vault transparency page so a
|
|
501
|
+
// partner can compose exactly the subset they want (e.g. Performance without
|
|
502
|
+
// the collateral-ratio card). Every method: public endpoint, no API key, one
|
|
503
|
+
// HTTPS request, zero RPC, snapshot-backed (hourly-ish; cache ≥60s).
|
|
504
|
+
// -------------------------------------------------------------------------
|
|
505
|
+
/**
|
|
506
|
+
* Fetch the latest position snapshot for a vault, grouped per wallet — the
|
|
507
|
+
* data behind the transparency Overview tab (strategy breakdown, backing
|
|
508
|
+
* composition, vault buffer, per-wallet table, headline TVL).
|
|
509
|
+
*
|
|
510
|
+
* Public `GET /upshift/positions/{vault_address}`; no API key. One HTTPS
|
|
511
|
+
* request, no RPC. Snapshots land hourly; every field is from the single
|
|
512
|
+
* `snapshot_at` instant. Vault buffer = `total_nav − Σ subaccounts[].total_usd`;
|
|
513
|
+
* `reported_tvl` is the vault-contract-reported total assets from the same snapshot.
|
|
514
|
+
*
|
|
515
|
+
* @param params.vault EVM vault address.
|
|
516
|
+
* @param params.chainId Numeric chain id the vault lives on.
|
|
517
|
+
* @returns {@link ITransparencyPositions}.
|
|
518
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
519
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
520
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
521
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
522
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
523
|
+
* @example
|
|
524
|
+
* ```ts
|
|
525
|
+
* const p = await sdk.apiModule.getVaultPositionSnapshot({ vault: '0x36eDbF0C834591BFdfCaC0Ef9605528c75c406aA', chainId: 143 });
|
|
526
|
+
* const buffer = p.total_nav - p.subaccounts.reduce((a, s) => a + s.total_usd, 0);
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
async getVaultPositionSnapshot(params) {
|
|
530
|
+
const method = 'getVaultPositionSnapshot';
|
|
531
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
532
|
+
const data = await (0, fetcher_1.fetchTransparencyPositions)(params.vault, params.chainId, this.headers ?? undefined);
|
|
533
|
+
assertTransparencyEnvelope(data, method);
|
|
534
|
+
return data;
|
|
535
|
+
}
|
|
536
|
+
/**
|
|
537
|
+
* Fetch the backing / supply / collateral-ratio time series behind the
|
|
538
|
+
* Performance tab's "Backing vs Supply" and "Collateral Ratio" charts, and
|
|
539
|
+
* the Overview sidebar's 7-day deltas.
|
|
540
|
+
*
|
|
541
|
+
* Public `GET /upshift/unrealized_pnl?fields=ratio`; no API key. One HTTPS
|
|
542
|
+
* request, no RPC. Points are hourly, returned newest-first — sort before
|
|
543
|
+
* charting. `actual_tvl` = backing (mark-to-market), `tvl_on_vault` = supply
|
|
544
|
+
* (vault-reported), `adjusted_redeem_ratio` = collateral ratio.
|
|
545
|
+
*
|
|
546
|
+
* Unlike the chain-scoped transparency endpoints (positions, fees,
|
|
547
|
+
* governance…), this one is keyed by vault address only and accepts
|
|
548
|
+
* non-EVM (Solana / Stellar) vaults — same contract as
|
|
549
|
+
* {@link UpshiftApi.getVaultUnrealizedPnlHistory}, which it shares a route with.
|
|
550
|
+
*
|
|
551
|
+
* @param params.vault Vault address (EVM, Solana, or Stellar).
|
|
552
|
+
* @param params.startDate Optional inclusive lower bound, `YYYY-MM-DD`.
|
|
553
|
+
* @param params.endDate Optional inclusive upper bound, `YYYY-MM-DD`.
|
|
554
|
+
* @param params.limit Optional max points.
|
|
555
|
+
* @returns Array of {@link ITransparencyRatioPoint}; empty when no history.
|
|
556
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
557
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
558
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
559
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
560
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
561
|
+
* @example
|
|
562
|
+
* ```ts
|
|
563
|
+
* const pts = await sdk.apiModule.getVaultBackingSeries({ vault, startDate: '2026-08-01' });
|
|
564
|
+
* const ratio = pts.map((p) => p.adjusted_redeem_ratio * 100); // percent
|
|
565
|
+
* ```
|
|
566
|
+
*/
|
|
567
|
+
async getVaultBackingSeries(params) {
|
|
568
|
+
const method = 'getVaultBackingSeries';
|
|
569
|
+
assertVaultAddress(params.vault, method);
|
|
570
|
+
assertIsoDate(method, 'startDate', params.startDate);
|
|
571
|
+
assertIsoDate(method, 'endDate', params.endDate);
|
|
572
|
+
if (params.limit !== undefined &&
|
|
573
|
+
(!Number.isInteger(params.limit) ||
|
|
574
|
+
params.limit < 1 ||
|
|
575
|
+
params.limit > 1000)) {
|
|
576
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: limit must be an integer between 1 and 1000, got ${params.limit}.`);
|
|
577
|
+
}
|
|
578
|
+
const data = await (0, fetcher_1.fetchTransparencyRatioSeries)(params.vault, params.startDate, params.endDate, params.limit, this.headers ?? undefined);
|
|
579
|
+
assertTransparencyArray(data, method);
|
|
580
|
+
return data;
|
|
581
|
+
}
|
|
582
|
+
/**
|
|
583
|
+
* Fetch the smoothed 7-day APY series — the exact series the Upshift app
|
|
584
|
+
* charts (Overview "APY last 30 days" and Performance "APY Over Time").
|
|
585
|
+
*
|
|
586
|
+
* Public `GET /upshift/historical_apy/chart`; no API key. One HTTPS request,
|
|
587
|
+
* no RPC. The backend marks this route deprecated in its OpenAPI spec but it
|
|
588
|
+
* remains the series the Upshift app itself charts; this wrapper tracks it.
|
|
589
|
+
* The backend applies a rolling-median/mean smoothing filter server-side
|
|
590
|
+
* when `applySmoothing` is true (the app default); computing APY locally from
|
|
591
|
+
* raw share ratios will NOT match the published figures.
|
|
592
|
+
*
|
|
593
|
+
* Unlike the chain-scoped transparency endpoints (positions, fees,
|
|
594
|
+
* governance…), this one is keyed by vault address only and accepts
|
|
595
|
+
* non-EVM (Solana / Stellar) vaults.
|
|
596
|
+
*
|
|
597
|
+
* @param params.vault Vault address (EVM, Solana, or Stellar).
|
|
598
|
+
* @param params.daysAgo Window length in days; pass `-1` for the full history since inception. Default 30.
|
|
599
|
+
* @param params.averagingPeriodDays Rolling window for the annualized return; must be ≥ 2. Default 7 (the app's "7D APY").
|
|
600
|
+
* @param params.applySmoothing Apply the backend smoothing filter. Default true.
|
|
601
|
+
* @returns {@link ITransparencyApySeries} — `labels` are `M/D/YYYY`, `values` are decimal fractions (0.0245 = 2.45%). Empty arrays when the vault has no data.
|
|
602
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
603
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
604
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
605
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
606
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
607
|
+
* @example
|
|
608
|
+
* ```ts
|
|
609
|
+
* const apy = await sdk.apiModule.getVaultSmoothedApy({ vault, daysAgo: 30 });
|
|
610
|
+
* console.log(apy.values.at(-1)); // latest 7D APY as a fraction
|
|
611
|
+
* ```
|
|
612
|
+
*/
|
|
613
|
+
async getVaultSmoothedApy(params) {
|
|
614
|
+
const method = 'getVaultSmoothedApy';
|
|
615
|
+
assertVaultAddress(params.vault, method);
|
|
616
|
+
const daysAgo = params.daysAgo ?? 30;
|
|
617
|
+
// `0` is deliberately rejected: the backend happens to treat `days_ago=0`
|
|
618
|
+
// as "full history" (same as -1) but only -1 is documented, and a caller
|
|
619
|
+
// passing 0 almost certainly means "today", not "everything". Forcing the
|
|
620
|
+
// explicit sentinel avoids silently returning the whole series.
|
|
621
|
+
if (!Number.isInteger(daysAgo) || (daysAgo < 1 && daysAgo !== -1)) {
|
|
622
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: daysAgo must be a positive integer (≥ 1) or -1 for full history, got ${params.daysAgo}. 0 is not accepted — pass -1 for the full series.`);
|
|
623
|
+
}
|
|
624
|
+
const averaging = params.averagingPeriodDays ?? 7;
|
|
625
|
+
if (!Number.isInteger(averaging) || averaging < 2) {
|
|
626
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: averagingPeriodDays must be an integer ≥ 2, got ${params.averagingPeriodDays}.`);
|
|
627
|
+
}
|
|
628
|
+
const envelope = await (0, fetcher_1.fetchTransparencySmoothedApy)(params.vault, daysAgo, averaging, params.applySmoothing ?? true, this.headers ?? undefined);
|
|
629
|
+
// The endpoint reports not-found / bad-args IN-BODY over HTTP 200. The
|
|
630
|
+
// live shape for those is
|
|
631
|
+
// { data: { labels: [], values: [] }, average_apy: null, status: 404|400, error: "…" }
|
|
632
|
+
// i.e. `data` is never null — it passes `shapeOk` below and falls through
|
|
633
|
+
// to the normal return as an empty series (charts render their empty
|
|
634
|
+
// state). The `!shapeOk && status 404/400` branch is a defensive mirror
|
|
635
|
+
// in case the backend ever sends `data: null` with those statuses.
|
|
636
|
+
// `data: null` with `status: 200` has never been observed; if it shows up
|
|
637
|
+
// it IS a contract change and must fail loudly rather than hand partners
|
|
638
|
+
// a bogus empty chart.
|
|
639
|
+
const data = envelope?.data;
|
|
640
|
+
const shapeOk = data !== null &&
|
|
641
|
+
typeof data === 'object' &&
|
|
642
|
+
Array.isArray(data.labels) &&
|
|
643
|
+
Array.isArray(data.values);
|
|
644
|
+
if (!shapeOk) {
|
|
645
|
+
if (envelope?.status === 404 || envelope?.status === 400) {
|
|
646
|
+
return { labels: [], values: [], average_apy: null };
|
|
647
|
+
}
|
|
648
|
+
throw new errors_1.UpshiftServerError(200, `${method}: unexpected response shape from the Upshift API — expected { data: { labels, values } }. The backend contract may have changed; refresh packages/sdk/api-spec and update the SDK.`);
|
|
649
|
+
}
|
|
650
|
+
return {
|
|
651
|
+
labels: data.labels,
|
|
652
|
+
values: data.values,
|
|
653
|
+
// average_apy sits at the envelope top level, beside `data`.
|
|
654
|
+
average_apy: envelope?.average_apy ?? null,
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Fetch daily allocation history per protocol — the Performance tab's
|
|
659
|
+
* "Allocation Over Time" chart.
|
|
660
|
+
*
|
|
661
|
+
* Public `GET /upshift/historical_allocations/{vault_address}`; no API key.
|
|
662
|
+
* One HTTPS request, no RPC.
|
|
663
|
+
*
|
|
664
|
+
* @param params.vault EVM vault address.
|
|
665
|
+
* @param params.chainId Numeric chain id.
|
|
666
|
+
* @param params.startDate Optional inclusive lower bound, `YYYY-MM-DD`.
|
|
667
|
+
* @param params.endDate Optional inclusive upper bound, `YYYY-MM-DD`.
|
|
668
|
+
* @returns {@link ITransparencyHistoricalAllocations}.
|
|
669
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
670
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
671
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
672
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
673
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
674
|
+
* @example
|
|
675
|
+
* ```ts
|
|
676
|
+
* const h = await sdk.apiModule.getVaultHistoricalAllocations({ vault, chainId: 143, startDate: '2026-08-01' });
|
|
677
|
+
* const byDate = Map.groupBy(h.points, (p) => p.date);
|
|
678
|
+
* ```
|
|
679
|
+
*/
|
|
680
|
+
async getVaultHistoricalAllocations(params) {
|
|
681
|
+
const method = 'getVaultHistoricalAllocations';
|
|
682
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
683
|
+
assertIsoDate(method, 'startDate', params.startDate);
|
|
684
|
+
assertIsoDate(method, 'endDate', params.endDate);
|
|
685
|
+
const data = await (0, fetcher_1.fetchTransparencyHistoricalAllocations)(params.vault, params.chainId, params.startDate, params.endDate, this.headers ?? undefined);
|
|
686
|
+
assertTransparencyEnvelope(data, method);
|
|
687
|
+
return data;
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Fetch a vault's fee configuration — the Performance tab's fee card.
|
|
691
|
+
*
|
|
692
|
+
* Public `GET /upshift/fees/{vault_address}`; no API key. One HTTPS
|
|
693
|
+
* request, no RPC. Percent fields are already scaled (`management_fee_pct`
|
|
694
|
+
* of `1.5` means 1.5%).
|
|
695
|
+
*
|
|
696
|
+
* @param params.vault EVM vault address.
|
|
697
|
+
* @param params.chainId Numeric chain id.
|
|
698
|
+
* @returns {@link ITransparencyFees}.
|
|
699
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
700
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
701
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
702
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
703
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
704
|
+
* @example
|
|
705
|
+
* ```ts
|
|
706
|
+
* const fees = await sdk.apiModule.getVaultFeeConfig({ vault, chainId: 143 });
|
|
707
|
+
* console.log(`${fees.management_fee_pct}% mgmt / ${fees.performance_fee_pct}% perf`);
|
|
708
|
+
* ```
|
|
709
|
+
*/
|
|
710
|
+
async getVaultFeeConfig(params) {
|
|
711
|
+
const method = 'getVaultFeeConfig';
|
|
712
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
713
|
+
const data = await (0, fetcher_1.fetchTransparencyFees)(params.vault, params.chainId, this.headers ?? undefined);
|
|
714
|
+
assertTransparencyEnvelope(data, method);
|
|
715
|
+
return data;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Fetch the vault's privileged addresses (owner / operators) with custody
|
|
719
|
+
* enrichment — the Governance tab's "Vault Roles" card.
|
|
720
|
+
*
|
|
721
|
+
* Public `GET /upshift/governance/{vault_address}/roles`; no API key. One
|
|
722
|
+
* HTTPS request from the SDK (the backend performs the on-chain reads).
|
|
723
|
+
* Third-party enrichment failures (Safe / Fordefi) degrade rows and append
|
|
724
|
+
* to `warnings` rather than failing.
|
|
725
|
+
*
|
|
726
|
+
* @param params.vault EVM vault address.
|
|
727
|
+
* @param params.chainId Numeric chain id.
|
|
728
|
+
* @returns {@link ITransparencyGovernanceRoles}.
|
|
729
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
730
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
731
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
732
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
733
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
734
|
+
* @example
|
|
735
|
+
* ```ts
|
|
736
|
+
* const { roles, warnings } = await sdk.apiModule.getVaultGovernanceRoles({ vault, chainId: 143 });
|
|
737
|
+
* const owner = roles.find((r) => r.role === 'owner'); // owner?.is_safe → Safe threshold in safe_threshold
|
|
738
|
+
* ```
|
|
739
|
+
*/
|
|
740
|
+
async getVaultGovernanceRoles(params) {
|
|
741
|
+
const method = 'getVaultGovernanceRoles';
|
|
742
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
743
|
+
const data = await (0, fetcher_1.fetchTransparencyGovernanceRoles)(params.vault, params.chainId, this.headers ?? undefined);
|
|
744
|
+
assertTransparencyEnvelope(data, method);
|
|
745
|
+
return data;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Fetch the integrations each vault wallet is whitelisted to operate —
|
|
749
|
+
* the Governance tab's "Vault Permissions" table.
|
|
750
|
+
*
|
|
751
|
+
* Public `GET /upshift/governance/{vault_address}/permissions`; no API key.
|
|
752
|
+
* One HTTPS request, no RPC.
|
|
753
|
+
*
|
|
754
|
+
* @param params.vault EVM vault address.
|
|
755
|
+
* @param params.chainId Numeric chain id.
|
|
756
|
+
* @returns {@link ITransparencyGovernancePermissions}.
|
|
757
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
758
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
759
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
760
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
761
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
762
|
+
* @example
|
|
763
|
+
* ```ts
|
|
764
|
+
* const { permissions } = await sdk.apiModule.getVaultGovernancePermissions({ vault, chainId: 143 });
|
|
765
|
+
* for (const p of permissions) console.log(p.integration, p.functions.join(','));
|
|
766
|
+
* ```
|
|
767
|
+
*/
|
|
768
|
+
async getVaultGovernancePermissions(params) {
|
|
769
|
+
const method = 'getVaultGovernancePermissions';
|
|
770
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
771
|
+
const data = await (0, fetcher_1.fetchTransparencyGovernancePermissions)(params.vault, params.chainId, this.headers ?? undefined);
|
|
772
|
+
assertTransparencyEnvelope(data, method);
|
|
773
|
+
return data;
|
|
774
|
+
}
|
|
775
|
+
/**
|
|
776
|
+
* Fetch the vault's timelock queue — the Governance tab's "Pending
|
|
777
|
+
* Timelocks" table. Defaults to pending (`scheduled`) requests.
|
|
778
|
+
*
|
|
779
|
+
* Public `GET /upshift/governance/{vault_address}/timelocks`; no API key.
|
|
780
|
+
* `executable_at` is `scheduled_at + TIMELOCK_DURATION()` read live from
|
|
781
|
+
* the timelock contract; null (plus a warning) when that read failed.
|
|
782
|
+
* The default filter is pending only — the list is often empty; pass
|
|
783
|
+
* `status: 'all'` for history. `getTimelockRequests` returns the raw
|
|
784
|
+
* backend rows; this returns the dashboard view (labels, `executable_at`,
|
|
785
|
+
* warnings).
|
|
786
|
+
*
|
|
787
|
+
* @param params.vault EVM vault address.
|
|
788
|
+
* @param params.chainId Numeric chain id.
|
|
789
|
+
* @param params.status Filter: a single {@link ITransparencyTimelockStatus} or `'all'`. Default `'scheduled'`. Any other string is rejected with `UpshiftValidationError` before a request is made.
|
|
790
|
+
* @returns {@link ITransparencyTimelocks}.
|
|
791
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
792
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
793
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
794
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
795
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
796
|
+
* @example
|
|
797
|
+
* ```ts
|
|
798
|
+
* const { timelocks } = await sdk.apiModule.getVaultGovernanceTimelocks({ vault, chainId: 1 }); // pending only
|
|
799
|
+
* const ready = timelocks.filter((t) => t.executable_at && Date.parse(`${t.executable_at}Z`) <= Date.now());
|
|
800
|
+
* ```
|
|
801
|
+
*/
|
|
802
|
+
async getVaultGovernanceTimelocks(params) {
|
|
803
|
+
const method = 'getVaultGovernanceTimelocks';
|
|
804
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
805
|
+
assertOneOf(method, 'status', params.status, TRANSPARENCY_TIMELOCK_STATUSES);
|
|
806
|
+
const data = await (0, fetcher_1.fetchTransparencyGovernanceTimelocks)(params.vault, params.chainId, params.status, this.headers ?? undefined);
|
|
807
|
+
assertTransparencyEnvelope(data, method);
|
|
808
|
+
return data;
|
|
809
|
+
}
|
|
810
|
+
/**
|
|
811
|
+
* Fetch one page of the vault's governance audit log, newest first — the
|
|
812
|
+
* Governance tab's "Audit Log" timeline. Merges live timelock events with
|
|
813
|
+
* manually recorded entries (attestations, permission changes).
|
|
814
|
+
*
|
|
815
|
+
* Public `GET /upshift/governance/{vault_address}/audit_log`; no API key.
|
|
816
|
+
* Paginate with `before` = the last returned entry's `timestamp` while
|
|
817
|
+
* `has_more` is true (exclusive cursor; ties at the exact boundary
|
|
818
|
+
* timestamp are skipped, never duplicated).
|
|
819
|
+
*
|
|
820
|
+
* @param params.vault EVM vault address.
|
|
821
|
+
* @param params.chainId Numeric chain id.
|
|
822
|
+
* @param params.category Optional {@link ITransparencyAuditCategory} filter. Any other string is rejected with `UpshiftValidationError` before a request is made.
|
|
823
|
+
* @param params.before Optional exclusive cursor — pass the previous page's last `entry.timestamp` back verbatim (naive-UTC, no offset).
|
|
824
|
+
* @param params.limit Page size, 1–200. Backend default 50.
|
|
825
|
+
* @returns {@link ITransparencyAuditLog}.
|
|
826
|
+
* @throws UpshiftValidationError When arguments fail validation (no request is made).
|
|
827
|
+
* @throws UpshiftServerError When the API responds non-2xx (e.g. unknown vault 404, non-EVM vault 422).
|
|
828
|
+
* @throws UpshiftServerError (status 200) When the body is not the documented shape — backend contract drift.
|
|
829
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
830
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
831
|
+
* @example
|
|
832
|
+
* ```ts
|
|
833
|
+
* // Walk the whole log, newest first.
|
|
834
|
+
* let before: string | undefined;
|
|
835
|
+
* do {
|
|
836
|
+
* const page = await sdk.apiModule.getVaultGovernanceAuditLog({ vault, chainId: 1, before, limit: 50 });
|
|
837
|
+
* for (const e of page.entries) console.log(e.timestamp, e.type, e.summary);
|
|
838
|
+
* before = page.has_more ? page.entries.at(-1)?.timestamp : undefined;
|
|
839
|
+
* } while (before);
|
|
840
|
+
* ```
|
|
841
|
+
*/
|
|
842
|
+
async getVaultGovernanceAuditLog(params) {
|
|
843
|
+
const method = 'getVaultGovernanceAuditLog';
|
|
844
|
+
assertTransparencyArgs(method, params.vault, params.chainId);
|
|
845
|
+
assertOneOf(method, 'category', params.category, TRANSPARENCY_AUDIT_CATEGORIES);
|
|
846
|
+
if (params.limit !== undefined &&
|
|
847
|
+
(!Number.isInteger(params.limit) ||
|
|
848
|
+
params.limit < 1 ||
|
|
849
|
+
params.limit > 200)) {
|
|
850
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: limit must be an integer between 1 and 200, got ${params.limit}.`);
|
|
851
|
+
}
|
|
852
|
+
const data = await (0, fetcher_1.fetchTransparencyGovernanceAuditLog)(params.vault, params.chainId, params.category, params.before, params.limit, this.headers ?? undefined);
|
|
853
|
+
assertTransparencyEnvelope(data, method);
|
|
854
|
+
return data;
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Fetch the historical unrealized-PnL series for a vault, newest first,
|
|
858
|
+
* as computed by the Upshift backend from periodic vault snapshots.
|
|
859
|
+
*
|
|
860
|
+
* Makes one HTTPS request to the public Upshift API; no RPC calls.
|
|
861
|
+
*
|
|
862
|
+
* @param params.vault Vault address (EVM `0x…`, Solana, or Stellar).
|
|
863
|
+
* @param params.limit Maximum number of snapshots to return (1–1000). Backend default applies when omitted.
|
|
864
|
+
* @returns Array of {@link IUnrealizedPnlSnapshot}; empty when the backend has no history for the vault.
|
|
865
|
+
* @throws UpshiftValidationError When `vault` is not a valid address or `limit` is out of range.
|
|
866
|
+
* @throws UpshiftServerError When the API responds with a 5xx, or returns a body that is not a snapshot array.
|
|
867
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
868
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
869
|
+
* @example
|
|
870
|
+
* const series = await sdk.getVaultUnrealizedPnlHistory({ vault: '0x36eDbF0C834591BFdfCaC0Ef9605528c75c406aA', limit: 30 });
|
|
871
|
+
* console.log(series[0]?.unrealizedPnlInAsset);
|
|
872
|
+
*/
|
|
873
|
+
async getVaultUnrealizedPnlHistory(params) {
|
|
874
|
+
const method = 'getVaultUnrealizedPnlHistory';
|
|
875
|
+
assertVaultAddress(params.vault, method);
|
|
876
|
+
if (params.limit !== undefined &&
|
|
877
|
+
(!Number.isInteger(params.limit) ||
|
|
878
|
+
params.limit < 1 ||
|
|
879
|
+
params.limit > 1000)) {
|
|
880
|
+
throw new errors_1.UpshiftValidationError('INVALID_INPUT', `${method}: limit must be an integer between 1 and 1000, got ${params.limit}.`);
|
|
881
|
+
}
|
|
882
|
+
const endpoint = core_1.WEBSERVER_ENDPOINTS.public.pnl.unrealizedHistory(params.vault, params.limit);
|
|
883
|
+
const response = await (0, fetcher_2.fetchUpshiftPublic)(endpoint);
|
|
884
|
+
const data = await response.json();
|
|
885
|
+
assertSnapshotArray(data, method);
|
|
886
|
+
return data.map(toUnrealizedPnlSnapshot);
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Fetch the latest unrealized-PnL snapshot for every vault the backend
|
|
890
|
+
* tracks — one entry per vault.
|
|
891
|
+
*
|
|
892
|
+
* Makes one HTTPS request to the public Upshift API; no RPC calls.
|
|
893
|
+
*
|
|
894
|
+
* @returns Array of {@link IUnrealizedPnlSnapshot}, one per tracked vault.
|
|
895
|
+
* @throws UpshiftServerError When the API responds with a 5xx, or returns a body that is not a snapshot array.
|
|
896
|
+
* @throws UpshiftRateLimitError When the API responds 429.
|
|
897
|
+
* @throws UpshiftTimeoutError When the request exceeds the SDK request timeout.
|
|
898
|
+
* @example
|
|
899
|
+
* const all = await sdk.getLatestUnrealizedPnl();
|
|
900
|
+
* const losing = all.filter((s) => s.unrealizedPnl < 0);
|
|
901
|
+
*/
|
|
902
|
+
async getLatestUnrealizedPnl() {
|
|
903
|
+
const method = 'getLatestUnrealizedPnl';
|
|
904
|
+
const response = await (0, fetcher_2.fetchUpshiftPublic)(core_1.WEBSERVER_ENDPOINTS.public.pnl.unrealizedLatest);
|
|
905
|
+
const data = await response.json();
|
|
906
|
+
assertSnapshotArray(data, method);
|
|
907
|
+
return data.map(toUnrealizedPnlSnapshot);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
exports.UpshiftApi = UpshiftApi;
|
|
911
|
+
//# sourceMappingURL=main.js.map
|