Releases: StrobeLabs/perpcity-sdk
Release list
v0.14.1 — Complete PERP_ABI with trade/position events
Re-release of 0.14.0 (which failed to publish — Node 20 / npm@latest breakage, fixed in #59; the v0.14.0 tag is reserved by immutable releases). No source changes.
Added
PERP_ABI now includes all 20 Perp trade/position "free events" that forge inspect omits — TakerOpened, TakerAdjusted, TakerClosed, TakerBackstopped, the five Maker* events, plus pool/market-state and tick events (MarginTransferred, OpenInterestUpdated, RatesAndEmasRefreshed, CumulativesAccrued, CapacityUpdated, Donated, LossSocialized, BadDebtAccounted, TickInitialized, TickDeleted, TicksCrossed).
Consumers can now decodeEventLog({ abi: PERP_ABI, ... }) on any Perp trade log. Vendored from the deployed v0.1.0 contract; all 20 topic0 selectors verified against the indexer ABI. See #58.
v0.13.0
Adjust primitives for position adjustment:
- adjustTaker / adjustMaker / adjustMargin now await transaction receipts and throw on revert (aligned with open/close). Return shape unchanged.
- estimateTakerAdjust: quote an arbitrary signed adjust delta via the client-side swap model (no eth_call).
- buildAdjustTakerCalls / buildAdjustMakerCalls: approve+adjust call batches for gasless userOp submission.
v0.12.0 — Multicall batching on the public client
Client-level viem batch.multicall: concurrent readContract reads aggregate into a single Multicall3 aggregate3 eth_call (one billed RPC request instead of N). Transport-level HTTP batching kept for non-aggregatable requests; the estimateLiquidity margin probe opts out (batch: false) to preserve its revert-marker semantics. Chains without a configured Multicall3 fall back to individual calls automatically.
See CHANGELOG.md for details.
v0.11.0 — Maker liquidity sized to the on-chain margin check
LP opens no longer revert with MarginRatioTooLow at the sizes the SDK itself recommends.
Changed
- Breaking:
estimateLiquiditynow requires the perp address as its second argument:estimateLiquidity(context, perpAddress, tickLower, tickUpper, usdScaled). estimateLiquiditysizes liquidity to the on-chain maker margin check instead of the naive amount1 formula. The old formula targeted a notional exactly equal to the margin, which the contract's rounding pushed 1-2 units past the 100% maker initial margin ratio. The estimate now:- values below-range positions exactly, replicating the contract rounding (max healthy liquidity is
floor((margin - 2) * Q96 / sqrtPriceDiff), validated against mainnet); - values straddling and above-range positions at the larger of the AMM price and beacon index (ranges above the current price were previously sized as USD exposure and always reverted);
- verifies the result with an
eth_callsimulation ofopenMakerand bisects down to the true boundary when the mark price sits above both proxies.
- values below-range positions exactly, replicating the contract rounding (max healthy liquidity is
getSqrtRatioAtTickrounds up the final shift to match the contract's TickMath.
v0.10.0 — Price-impacted estimateTakerPosition
Quotes now reflect real AMM price impact.
Changed
estimateTakerPositionsimulates the exact-perp-in swap against the pool curve instead of returning the flat mark price.fillPriceandusdDeltanow reflect real price impact, andusdDeltais suitable to feed straight intocalculateTakerSlippageLimitfor anamt1Limitthat won't spuriously revert withMaxAmtExceededon shallow pools.- New
exceedsLiquidityfield onEstimateTakerPositionResult— set when an order is larger than the current active-liquidity region can fill (a strong pre-submit signal ofPriceImpactTooHigh).
Added
PerpDataexposessqrtPriceX96andliquidityfrompoolState(no new RPC).simulateTakerSwap(...)utility — the constant-liquidity exact-perp-in swap math, exported for callers holding pool state.
Limitations
Single active-liquidity-region approximation: exact within the current tick, understates impact once a swap would cross an initialized tick (only current active liquidity is available, not the full per-tick map). Fees are not modeled.
See PR #53.
v0.9.0 — Tier-2 calldata builders
Added — Tier-2 calldata builders
Raw-calldata builders for callers that submit transactions themselves (e.g. batching approve + trade into one ERC-4337 userOperation) instead of letting the SDK execute via walletClient.writeContract. Each mirrors the argument encoding of its execute-and-wait counterpart, so a built call hits the same contract path; fee headroom is omitted because userOp gas is handled by the bundler/paymaster.
buildApproveUsdcCall,buildOpenTakerPositionCall,buildOpenMakerPositionCallbuildAdjustTakerCall,buildAdjustMakerCall,buildClosePositionCallbuildOpenTakerPositionCalls/buildOpenMakerPositionCalls— full ordered batch that prepends a USDCapproveonly when allowance is short (maker coversmargin + maxAmt1In)CallDatatype ({ to, data, value })
Additive and non-breaking. See PR #52.
v0.8.3
Decode current contract errors: full custom-error ABI (MinAmtUnmet, MarginTooLow, MaxAmtExceeded, InsufficientLiquidityToFill, and friends) plus friendly messages in parseContractError — reverts no longer surface as "Contract error: Unknown".
v0.8.2
Changes
Fixes a 0.8.1 regression that broke every write on some Arbitrum providers (Alchemy): headroom fees were passed into simulateContract, and fee fields inside an eth_call make those nodes run the balance check against the RPC gas cap (uint64 max), rejecting every call with insufficient-funds.
- Fees now merge into the prepared request at
writeContracttime viawithFeeHeadroom; simulation requests carry no fee fields - Regression tests pin both request shapes (no fees in simulation, doubled fees on the write)
Full diff: v0.8.1...v0.8.2
v0.8.1
Changes
bounds.minMarginnow mirrors the contract'sMIN_OPENING_MARGIN(5e6 micro-USDC = $5, was a stale hardcoded $10); exported asMIN_OPENING_MARGIN_USD- All write paths pass explicit
maxFeePerGaswith 2x headroom (estimateFeesWithHeadroom), preventing intermittentFeeCapTooLowErrorrejections when the base fee moves between estimation and submission (frequent on Arbitrum Sepolia) parseContractErrormaps fee-cap-too-low failures to a retryableRPCErrorinstead ofContractError "Unknown"
Full diff: v0.8.0...v0.8.1
v0.8.0
Added
calculateTakerSlippageLimit(quote, isLong, slippagePercent)— derives the contract-nativeamt1LimitforopenTakerPositionfromusdDelta(the currency1 / USD leg the contract checks inPerpLogic.checkTakerAmountLimits): a ceiling on USD paid for longs, a floor on USD received for shorts. The slippage math now lives in the SDK instead of being reimplemented per app.
Changed
examples/taker.tsandexamples/wagmi-integration.tsusecalculateTakerSlippageLimitinstead of inlining the basis-point math.- Bumped
viemfrom^2.37.8to^2.46.1to align with the client and removeas neverwalletClient casts there. - Switched
tsconfigmoduleResolutionfromnodetobundlerso the newer viem's transitiveoxresolves to its bundled declarations (skipped byskipLibCheck) instead of its raw.tssource.