@steerprotocol/sdk 4.0.0-next.6 → 4.0.0-next.8
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/README.md +209 -7
- package/dist/index.cjs +10400 -6957
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +178 -10
- package/dist/index.d.mts +178 -10
- package/dist/index.mjs +10397 -6958
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -90,7 +90,8 @@ interface VaultMetadata {
|
|
|
90
90
|
readonly beaconName: string;
|
|
91
91
|
readonly createdAt: string;
|
|
92
92
|
readonly state: string | null;
|
|
93
|
-
|
|
93
|
+
/** Contract address or 32-byte V4 pool ID. */
|
|
94
|
+
readonly pool: Hex | null;
|
|
94
95
|
readonly poolKey?: string | null;
|
|
95
96
|
readonly token0: Address | null;
|
|
96
97
|
readonly token1: Address | null;
|
|
@@ -101,6 +102,8 @@ interface VaultMetadata {
|
|
|
101
102
|
|
|
102
103
|
This replaces address-only pages. Use `item.id` when passing a listed result to a vault getter.
|
|
103
104
|
`decimals` and `createdAt` retain their indexed string representation. Null fields remain null;
|
|
105
|
+
Unavailable indexed pool/token address fields represented by empty strings become `null`; the native zero address remains unchanged.
|
|
106
|
+
`pool` preserves either a contract address or a 32-byte V4 pool ID.
|
|
104
107
|
`poolKey` is omitted when the subgraph schema does not expose it. Only an explicit rejection of
|
|
105
108
|
that optional field permits querying without it; other GraphQL and transport errors propagate.
|
|
106
109
|
|
|
@@ -206,6 +209,26 @@ snapshots[0]?.total.token0.formatted;
|
|
|
206
209
|
snapshots[0]?.fees.net.token1.raw;
|
|
207
210
|
```
|
|
208
211
|
|
|
212
|
+
Opt in to independent vault failures with `allowFailure: true`:
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
const results = await steer.getVaultSnapshots(ChainId.Base, vaultAddresses, {
|
|
216
|
+
blockNumber,
|
|
217
|
+
allowFailure: true,
|
|
218
|
+
});
|
|
219
|
+
for (const [index, result] of results.entries()) {
|
|
220
|
+
if (result.status === "success") consume(vaultAddresses[index], result.snapshot);
|
|
221
|
+
else report(vaultAddresses[index], result.error);
|
|
222
|
+
}
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
This mode preserves an outcome for every input, including duplicates. Preflight and snapshot
|
|
226
|
+
reverts, decoding errors and vault validation failures stay with that vault. Registered readers
|
|
227
|
+
and overrides still run their original identity checks. Shared RPC/HTTP failures, malformed batch
|
|
228
|
+
responses and invalid shared contexts still reject the call. Provider feature rejection alone
|
|
229
|
+
selects the existing compatibility path. Ordinary bounded override pages still use two RPCs;
|
|
230
|
+
there is no batch splitting to locate a failed vault. Calls without this option remain atomic.
|
|
231
|
+
|
|
209
232
|
The deployment-level `steer.getDeployment(chainId).getVaultSnapshots(addresses, options)` is
|
|
210
233
|
identical. Results use the same `LiquidityVaultSnapshot` model as `vault.getSnapshot()`, in input
|
|
211
234
|
order, including duplicates. This method resolves identity and reads accounting; `getVaults()`
|
|
@@ -1346,9 +1369,11 @@ for (const key of page.items) {
|
|
|
1346
1369
|
|
|
1347
1370
|
A pool key contains `currency0`, `currency1`, `fee`, `tickSpacing`, and `hooks`. Currencies must be
|
|
1348
1371
|
sorted numerically. Key validation includes V4 fee flags and hook permission relationships.
|
|
1349
|
-
Pool IDs are `keccak256(abi.encode(key))`; the hash cannot be reversed. ID-only reads
|
|
1350
|
-
configured
|
|
1351
|
-
|
|
1372
|
+
Pool IDs are `keccak256(abi.encode(key))`; the hash cannot be reversed. ID-only reads use the
|
|
1373
|
+
configured data adapter to recover metadata and verify the complete key against its ID. Indexed
|
|
1374
|
+
adapters query their configured endpoint; RPC adapters use the onchain key index or initialization
|
|
1375
|
+
event recovery with an archival provider. Missing evidence fails clearly; a complete key avoids
|
|
1376
|
+
that dependency. Per-request HTTP overrides are
|
|
1352
1377
|
accepted by `getPoolKey`, ID-based `getPool`, `quote`, and `listPools`, including
|
|
1353
1378
|
ID-based family discovery through `steer.getPool`.
|
|
1354
1379
|
|
|
@@ -1727,9 +1752,24 @@ This initial family implementation uses original contract reads and the existing
|
|
|
1727
1752
|
reader with its deployless/override/Multicall fallback. A pinned resolved snapshot takes
|
|
1728
1753
|
16 RPCs normally or 19 through compatibility; latest adds one. Bulk reads use bounded
|
|
1729
1754
|
compatibility orchestration, not the optimized two-RPC V3/Algebra vault readers. BNB AMM
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1755
|
+
pool browsing and token filtering use the configured Uniswap V4 subgraph with the client's
|
|
1756
|
+
Graph API key or proxy. ID-only reads retain the onchain key resolver independently of indexer
|
|
1757
|
+
availability; missing historical key-index entries need archival RPC. Indexed keys whose mutable
|
|
1758
|
+
fees no longer match their IDs require RPC initialization logs to recover the original key.
|
|
1759
|
+
Steer indexed V4 token metadata is populated, and ERC-20 address, symbol and name searches are
|
|
1760
|
+
live-verified for the registered Reserve vaults. Direct address-based reads remain independently verified.
|
|
1761
|
+
|
|
1762
|
+
```ts
|
|
1763
|
+
const amm = steer.getAmm({
|
|
1764
|
+
chainId: ChainId.BSC,
|
|
1765
|
+
protocol: AmmProtocol.Uniswap,
|
|
1766
|
+
version: UniswapVersion.V4,
|
|
1767
|
+
});
|
|
1768
|
+
const pools = await amm.listPools({ token: { symbol: "USDC" }, limit: 25 });
|
|
1769
|
+
const nextPools = pools.nextCursor
|
|
1770
|
+
? await amm.listPools({ cursor: pools.nextCursor, limit: 25 })
|
|
1771
|
+
: undefined;
|
|
1772
|
+
```
|
|
1733
1773
|
See [deployment qualification and budgets](src/vault/adapters/uniswap-v4/qualification.md).
|
|
1734
1774
|
|
|
1735
1775
|
### Aerodrome Slipstream on Base
|
|
@@ -1851,3 +1891,165 @@ standalone claim, signing or broadcasting occurs. Empty vaults require explicit
|
|
|
1851
1891
|
Aerodrome's qualified helper accepts one raw initial share. One-sided vaults quote only the held asset.
|
|
1852
1892
|
|
|
1853
1893
|
See [vault qualification, accounting and budgets](src/vault/adapters/aerodrome/qualification.md).
|
|
1894
|
+
|
|
1895
|
+
|
|
1896
|
+
### Robinhood standalone Uniswap V4 snapshots
|
|
1897
|
+
|
|
1898
|
+
`MultiPositionUniswapV4NoOracle` uses the same standalone V4 snapshot reader as the qualified
|
|
1899
|
+
BNB Reserve deployment. The oracle difference belongs to tend validation, not snapshot accounting.
|
|
1900
|
+
Use `steer.getVaultSnapshots(ChainId.Robinhood, addresses, { blockNumber })` or a resolved vault's
|
|
1901
|
+
`getSnapshot()`. Exact proxy/beacon/implementation/helper identities, stored registry, pool routing
|
|
1902
|
+
and fees are checked at the selected block. Full pool keys are read from vault contracts; indexed
|
|
1903
|
+
pool listing remains unavailable; ID-only lookup uses the shared onchain key resolver. See the [deployment qualification](src/vault/adapters/uniswap-v4/qualification.md#robinhood-shared-snapshot-deployment).
|
|
1904
|
+
|
|
1905
|
+
V4 wallet discovery uses `listUserVaults()` with indexed candidates and onchain share balances,
|
|
1906
|
+
including shares acquired by transfer. Transfer-aware subgraph holdings are not required.
|
|
1907
|
+
Live tests cover BSC Reserve and Robinhood NoOracle holders for both ERC20 and native pairs,
|
|
1908
|
+
including pagination and compatibility reads. Follow every `nextCursor`, even when `items`
|
|
1909
|
+
is empty. Incomplete indexed token metadata still limits token-filtered discovery.
|
|
1910
|
+
|
|
1911
|
+
|
|
1912
|
+
### V4 pool-ID lookup without a pool indexer
|
|
1913
|
+
|
|
1914
|
+
`amm.getPool({ poolId })`, `amm.getPoolKey(poolId)` and client/bulk ID getters share the
|
|
1915
|
+
family data adapter's key resolution. The RPC adapter is reusable on any configured canonical
|
|
1916
|
+
Uniswap V4 deployment. It verifies the configured PositionManager and the full key hash.
|
|
1917
|
+
Pools absent from that contract's key index are recovered from their original initialization
|
|
1918
|
+
event using historical RPC state. Recovery searches recent history first; older pools require
|
|
1919
|
+
an archival provider. Missing history
|
|
1920
|
+
is an error, not a fabricated key. Pool browsing remains separate and requires an indexed adapter.
|
|
1921
|
+
Base retains its existing indexed adapter by default. BNB combines indexed browsing with RPC key
|
|
1922
|
+
resolution; Robinhood uses RPC key resolution without indexed pool browsing.
|
|
1923
|
+
|
|
1924
|
+
|
|
1925
|
+
### BSC PancakeSwap V3 vault snapshots
|
|
1926
|
+
|
|
1927
|
+
`MultiPositionPancake` vaults on BSC use the shared `UniswapV3Vault` implementation and
|
|
1928
|
+
existing fixed-fee reader. Resolve by address with `getLiquidityVault(ChainId.BSC, address)`
|
|
1929
|
+
or use `getVaultSnapshots`. Pool factory, registry, beacon, implementation and proxy runtime
|
|
1930
|
+
are checked at the operation block. Only the exact qualified deployment is supported.
|
|
1931
|
+
|
|
1932
|
+
This implementation reserves accrued Steer and strategist fees separately and takes a fixed
|
|
1933
|
+
30% cut of earned fees. Its fee cut is rounded once over all ranges, matching original
|
|
1934
|
+
`poke()` followed by `getTotalAmounts()` in a single read-only simulation. Other V3 deployments
|
|
1935
|
+
keep their existing rounding policy. BSC bulk vault reads retain bounded compatibility
|
|
1936
|
+
orchestration; this addition does not introduce a two-RPC bulk optimization.
|
|
1937
|
+
|
|
1938
|
+
See [Pancake vault qualification](src/vault/adapters/uniswap-v3/pancake-qualification.md) for
|
|
1939
|
+
identities, funded fixtures, retained-response regressions and live test coverage. Separate funded user-flow qualification now covers deposit quotes/preparation, partial/full
|
|
1940
|
+
withdrawals, user positions and indexed wallet balance scanning.
|
|
1941
|
+
|
|
1942
|
+
|
|
1943
|
+
### Camelot legacy vault snapshots on Arbitrum
|
|
1944
|
+
|
|
1945
|
+
`MultiPositionCamelot` vaults on Arbitrum use the shared `AlgebraLegacyVault` implementation.
|
|
1946
|
+
Resolve with `getLiquidityVault(ChainId.Arbitrum, address)` or call `getVaultSnapshots`.
|
|
1947
|
+
The exact beacon/implementation, proxy code, stored registry, pool factory/deployer and
|
|
1948
|
+
currencies are checked at the snapshot block. This covers the qualified legacy directional
|
|
1949
|
+
Algebra deployment; Camelot Integral and other beacon types are separate registrations.
|
|
1950
|
+
|
|
1951
|
+
A directional override reader preserves both pool swap fees and community shares while
|
|
1952
|
+
reusing existing position/fee accounting. Vault fees are fixed at 15% with aggregate rounding.
|
|
1953
|
+
Normal resolved snapshots take two RPC calls. Unsupported overrides use original-contract
|
|
1954
|
+
compatibility reads and the AMM's existing pool-reader fallbacks. Live checks cover funded
|
|
1955
|
+
three-range and five-range vaults. Bulk snapshots use bounded existing orchestration.
|
|
1956
|
+
See [Camelot qualification](src/vault/adapters/algebra-legacy/camelot-qualification.md).
|
|
1957
|
+
Funded simulations now also verify deposit quotes/preparation, partial/full withdrawals, user
|
|
1958
|
+
positions and wallet discovery. Arbitrum deposit accounting uses the verified Multicall3 deployment.
|
|
1959
|
+
|
|
1960
|
+
|
|
1961
|
+
### Blackhole CL on Avalanche
|
|
1962
|
+
|
|
1963
|
+
Select pools with `{ protocol: AmmProtocol.Blackhole, version: BlackholeVersion.CL }`.
|
|
1964
|
+
Blackhole uses Integral-compatible pool reads with custom-deployer identity preserved.
|
|
1965
|
+
Pool and vault searches support token addresses, symbols, names and pagination.
|
|
1966
|
+
|
|
1967
|
+
The exact qualified `MultiPositionBlackHole` deployment resolves to `BlackholeVault` through
|
|
1968
|
+
`getLiquidityVault(ChainId.Avalanche, address)`. Snapshots include separate immutable `rewardAssets`
|
|
1969
|
+
and position-level `nftTokensOwed` diagnostics excluded from LP entitlement. Wallet discovery uses
|
|
1970
|
+
indexed vault candidates plus on-chain share balances. User positions and prepared ERC20 deposit
|
|
1971
|
+
and withdrawal flows have passed live simulations, including partial/full withdrawal rewards.
|
|
1972
|
+
AVAX inputs use an explicit WAVAX wrap before deposit. Native exits use a separate unwrap after
|
|
1973
|
+
withdrawal confirmation; standalone reward claims are not exposed. Vault reads use bounded
|
|
1974
|
+
compatibility calls, without a two-RPC guarantee.
|
|
1975
|
+
|
|
1976
|
+
See [qualification](src/vault/adapters/blackhole/qualification.md) for exact identities and evidence.
|
|
1977
|
+
Run `npm run test:integration:blackhole` with `AVALANCHE_RPC_URL` for the paced historical live suite.
|
|
1978
|
+
|
|
1979
|
+
|
|
1980
|
+
#### Blackhole AVAX deposit and exit
|
|
1981
|
+
|
|
1982
|
+
Use the zero address as the native AVAX input when the vault holds WAVAX:
|
|
1983
|
+
|
|
1984
|
+
```ts
|
|
1985
|
+
const plan = await vault.prepareDeposit({
|
|
1986
|
+
account,
|
|
1987
|
+
receiver,
|
|
1988
|
+
assets: [
|
|
1989
|
+
{ asset: zeroAddress, amount: avaxMaximum },
|
|
1990
|
+
{ asset: otherToken, amount: otherMaximum },
|
|
1991
|
+
],
|
|
1992
|
+
slippageBps: 50,
|
|
1993
|
+
});
|
|
1994
|
+
```
|
|
1995
|
+
|
|
1996
|
+
The ordered unsigned transactions wrap AVAX, approve tokens if necessary, then deposit.
|
|
1997
|
+
Submit them in order from `account`. Only the wrap transaction carries AVAX. Unused input
|
|
1998
|
+
remains WAVAX, as shown in the preview's underlying-token `unusedAmounts`. Other assets are
|
|
1999
|
+
not swapped. Avoid providing both AVAX and WAVAX in the same request.
|
|
2000
|
+
|
|
2001
|
+
Withdraw normally with `prepareWithdraw`. After confirmation, the WAVAX recipient can call
|
|
2002
|
+
`prepareUnwrapNative({ account: recipient, amount: actualWavaxReceived })` on `BlackholeVault`.
|
|
2003
|
+
This prepares a separate WAVAX withdrawal transaction that pays AVAX to `recipient` after
|
|
2004
|
+
checking its balance. Use actual received amounts rather than the earlier withdrawal preview.
|
|
2005
|
+
Both stages are separate wallet operations; preparation sends nothing.
|
|
2006
|
+
|
|
2007
|
+
|
|
2008
|
+
### Pancake V3 and Camelot user-flow verification
|
|
2009
|
+
|
|
2010
|
+
Run `npm run test:integration:vault-flows` with BSC and Arbitrum archival RPC URLs. This suite
|
|
2011
|
+
repeats actual-contract deposits/withdrawals and balance-based discovery at retained pinned blocks.
|
|
2012
|
+
It uses pinned public indexer responses and paces live RPC calls by 1.5 seconds. No Graph API
|
|
2013
|
+
credentials or Base RPC are needed for this isolated runner. Full historical state and temporary
|
|
2014
|
+
EOA code overrides must be supported. Native BNB/ETH wrapping helpers remain separate work.
|
|
2015
|
+
### Partial vault loading and pool reads
|
|
2016
|
+
|
|
2017
|
+
Strict calls still reject the whole batch. Opt in to ordered, immutable per-input outcomes:
|
|
2018
|
+
|
|
2019
|
+
```ts
|
|
2020
|
+
const vaults = await steer.getVaults(chainId, addresses, {
|
|
2021
|
+
blockNumber,
|
|
2022
|
+
metadata, // optional complete indexed VaultMetadata records
|
|
2023
|
+
allowFailure: true,
|
|
2024
|
+
});
|
|
2025
|
+
for (const result of vaults) {
|
|
2026
|
+
if (result.status === "success") console.log(result.vault.address);
|
|
2027
|
+
else console.log(result.error);
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
const pools = await amm.getPools(references, { blockNumber, allowFailure: true });
|
|
2031
|
+
for (const result of pools) {
|
|
2032
|
+
if (result.status === "success") console.log(result.pool);
|
|
2033
|
+
else console.log(result.error);
|
|
2034
|
+
}
|
|
2035
|
+
```
|
|
2036
|
+
|
|
2037
|
+
These methods preserve input order and duplicates. Unsupported implementations, absent V4 keys,
|
|
2038
|
+
and contract member failures do not discard successful members or trigger recursive splitting.
|
|
2039
|
+
Native readers retain their page sizes and RPC counts. Explicitly unsupported provider execution
|
|
2040
|
+
uses the existing bounded compatibility path. Shared RPC failures, invalid request context,
|
|
2041
|
+
malformed shared RPC responses, and shared vault metadata request failures still reject the call.
|
|
2042
|
+
`SteerClient.getPools(request)` discovery remains strict; partial pool reads use the selected
|
|
2043
|
+
AMM's `getPools(references, options)`.
|
|
2044
|
+
|
|
2045
|
+
|
|
2046
|
+
V4 partial ID reads isolate `V4PoolKeyNotFoundError` for a verified absent indexed key or
|
|
2047
|
+
uninitialized onchain pool. Shared indexer, JSON/schema, RPC, and unexpected key-adapter errors
|
|
2048
|
+
reject the request, including through registered adapter overrides. Custom V4 data adapters
|
|
2049
|
+
can throw `V4PoolKeyNotFoundError` to report an absent key explicitly.
|
|
2050
|
+
|
|
2051
|
+
Blackhole reward assets expose `unattributedReservedFees`: stored fee reserves not attributed
|
|
2052
|
+
to the current fee identifiers after a fee-policy replacement. These remain part of
|
|
2053
|
+
`reservedFees`, fully excluded from LP holdings. Current-recipient unpaid fees plus
|
|
2054
|
+
`unattributedReservedFees` reconcile to the stored reserve; current unclaimed fee cuts still
|
|
2055
|
+
reconcile exactly to the current policy.
|