lateral-sdk
v0.4.3
Published
`lateral-sdk` is the published TypeScript package for interacting with Lateral's offchain HTTP API and onchain protocol contracts from one package.
Readme
lateral-sdk
lateral-sdk is the published TypeScript package for interacting with Lateral's
offchain HTTP API and onchain protocol contracts from one package.
Today the package ships three main entrypoints:
createLateralApiClient(...)for HTTP readscreateLateralContractsClient(...)for viem-based contract reads and writescreateLateralSeaportClient(...)for Seaport listings, offers, and buyback flowscreateLateralSdk(...)as a backwards-compatible wrapper around all three
The contracts client currently covers:
- the auction stack
- the single-chain gacha stack
This package is publish-safe by design:
- no runtime imports from repo-only paths such as
/ABI/* - vendored ABIs live under
src/contracts/abi/* - public helpers, types, and ABIs are exported from the package root
Documentation Map
- Auction Guide: current auction SDK usage and common flows
- Gacha Guide: current gacha SDK usage and common flows
- Gacha Preflight Frontend Handoff: frontend implementation guide for gacha transaction simulations and UX states
- Seaport Guide: Seaport listings, offers, fulfillment, and gacha buyback helpers
- Seaport Marketplace Stack: system-level architecture across SDK, API orderbook, buybacks, and indexer responsibilities
- Protocol Spec: auction protocol architecture and business rules
- Gacha Fork Coverage: what the forked gacha e2e suite validates
Installation
This monorepo consumes the package through workspace dependencies:
{
"dependencies": {
"lateral-sdk": "workspace:*"
}
}For external consumers, the package is published to npm as lateral-sdk.
Public Surface
The package root exports:
createLateralApiClientcreateLateralContractsClientcreateLateralSeaportClientcreateLateralSdkencodeRgemInitParamsdecodeRgemInitParamsgetReadableContractErrorencodeFileParamNameLATERAL_CONTRACT_ADDRESSES_BY_CHAIN_ID- auction and gacha ABIs
- auction and gacha contract types
The ABI exports are intended for consumers that want direct viem usage while still sharing the same vendored ABI source as the SDK.
Quick Start
API client
import { createLateralApiClient } from "lateral-sdk";
const api = createLateralApiClient({
baseUrl: "https://your-api.example.com",
});
const auctions = await api.getAuctions({ limit: 20 });Contracts client
import { createLateralContractsClient } from "lateral-sdk";
import { createPublicClient, createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { sepolia } from "viem/chains";
const publicClient = createPublicClient({
chain: sepolia,
transport: http(process.env.SEPOLIA_RPC_URL),
});
const walletClient = createWalletClient({
chain: sepolia,
transport: http(process.env.SEPOLIA_RPC_URL),
account: privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`),
});
const contracts = createLateralContractsClient({
publicClient,
walletClient,
chainId: 11155111,
});If you only need reads, omit walletClient.
Seaport client
import { createLateralSeaportClient } from "lateral-sdk";
const seaport = createLateralSeaportClient({
walletClient,
});API Client
createLateralApiClient(...) is a thin typed wrapper over the current HTTP API.
const api = createLateralApiClient({
baseUrl,
fetch,
getAuthToken: () => token,
});Current methods:
getHealth()getAuctions({ limit? })getAuction({ auctionId })getAuctionBids({ auctionId, limit? })getVault({ address })getAccountActivity({ address, limit? })
The API client currently performs GET requests only and returns the response JSON as typed objects.
Contracts Client
createLateralContractsClient(...) resolves addresses, builds a shared viem
context, and exposes focused protocol modules.
const contracts = createLateralContractsClient({
publicClient,
walletClient,
chainId,
});
contracts.auction;
contracts.fees;
contracts.model;
contracts.gacha.access;
contracts.gacha.items;
contracts.gacha.machine;
contracts.gacha.randomness;
contracts.gacha.payments;Write helpers simulate via viem before sending transactions. The SDK also exposes explicit simulation methods:
await contracts.gacha.payments.simulatePurchaseSpins({ spins: 1n });
await contracts.gacha.payments.simulatePurchaseSpinsWithPermit2({
spins: 1n,
nonce,
deadline,
signature,
});
await contracts.gacha.items.simulateApprove({ tokenId, to: spender });
await contracts.gacha.items.simulateSetApprovalForAll({
operator,
approved: true,
});For the web frontend gacha purchase preflight, use the direct simulation flow in Gacha Preflight Frontend Handoff so the app can pass an explicit gas limit. Do not use the SDK payment simulation helpers in the web preflight hook unless the SDK surface is extended to accept gas overrides.
Address resolution
Addresses can come from:
addressesaddressesByChainIdLATERAL_CONTRACT_ADDRESSES_BY_CHAIN_ID
Example with direct overrides:
const contracts = createLateralContractsClient({
publicClient,
chainId: 11155111,
addresses: {
composableAuction: "0x...",
auctionFeeModuleV1: "0x...",
relativeGrowthExtendibleModel: "0x...",
},
});The resolved contracts.addresses object always uses the full stable shape,
with each known key present as Address | undefined.
Default deployments
The package currently ships Sepolia defaults for both domains:
- auction
ComposableAuctionAuctionFeeModuleV1RelativeGrowthExtendibleModel
- gacha
LateralAccessControlLateralRandomnessHubLateralItemsLateralGachaMachinePaymentGatewayERC20Permit2
See src/contracts/addresses.ts for the current mapping.
Auction Surface
The auction integration is split into three modules:
contracts.auctioncontracts.modelcontracts.fees
Common tasks:
- inspect an auction with
contracts.auction.getAuction(...) - read computed details with
contracts.auction.getAuctionDetails(...) - create auction model calldata with
encodeRgemInitParams(...) - quote next bid fees with
contracts.fees.getBidFee(...) - place and finalize bids through
contracts.auction.*
See Auction Guide for the full surface and examples.
Gacha Surface
The gacha integration is split into five modules:
contracts.gacha.accesscontracts.gacha.itemscontracts.gacha.machinecontracts.gacha.randomnesscontracts.gacha.payments
Common tasks:
- inspect machine, gateway, and hub state with
getState() - quote purchase cost with
contracts.gacha.payments.getTotalCost(...) - preflight purchase and approval transactions before opening the wallet modal
- buy through ERC-20 approval or Permit2
- deposit and withdraw prize inventory
- inspect randomness requests after purchase
See Gacha Guide for the full surface and examples. See Gacha Preflight Frontend Handoff for the frontend implementation flow.
Seaport Surface
The Seaport integration is exposed through createLateralSeaportClient(...).
Common tasks:
- create a listing for a pulled ERC-721
- create an offer for a pulled ERC-721
- create bulk listings or offers for multiple pulled items
- prepare listings, offers, and fulfillments to inspect required approvals and estimate gas before execution
- fulfill a signed Seaport order
- fulfill multiple orders in one best-effort transaction
- sign Seaport orders for an off-chain orderbook
- cancel or bulk-cancel your existing orders
- generate a 90%-of-WAD gacha buyback offer with a 10-minute validity window
- register and query Seaport domains
- serialize Seaport orders into JSON-safe payloads for an orderbook
- build orderbook-ready listing / offer / buyback records for persistence
By default, createLateralSeaportClient(...) tags created listings, offers, and
gacha buyback offers with the Lateral Seaport domain
DEFAULT_LATERAL_SEAPORT_DOMAIN ("lateral-gacha") and the open zero zone /
zone hash defaults exported as DEFAULT_LATERAL_SEAPORT_ZONE and
DEFAULT_LATERAL_SEAPORT_ZONE_HASH. Per-call domain, zone, and zoneHash
values still override those defaults. Pass null for a field to disable that
default for a specific call or through orderDefaults.
To tag Lateral orders with a dedicated Seaport zone for downstream event
filtering, pass a zone address through orderDefaults. For early testing, that
address can be an EOA:
import {
createLateralSeaportClient,
createLateralSeaportZoneOrderDefaults,
} from "lateral-sdk";
const seaport = createLateralSeaportClient({
walletClient,
orderDefaults: createLateralSeaportZoneOrderDefaults(
"0x1111111111111111111111111111111111111111",
),
});The helper keeps orders open by default (restrictedByZone: false) and uses the
default zero zoneHash, so the zone is a tag rather than a fulfillment gate.
The main persistence helpers are:
seaport.buildMarketplaceOrderRecord(...)on the client instancebuildSeaportMarketplaceOrderRecord(...)from the package root
The local repo now also includes a simple Seaport orderbook service in
apps/api. See Seaport Marketplace Stack
for the full cross-layer model.
See Seaport Guide for the full surface and examples.
Common Helpers
encodeRgemInitParams(...)
Encodes RGEMInitParams for ComposableAuction.createAuction(...).
const modelData = encodeRgemInitParams({
startTime: Math.floor(Date.now() / 1000),
duration: 3600,
extensionDuration: 300,
growthRateWAD: 5n * 10n ** 16n,
startingPrice: 1n * 10n ** 18n,
reservePrice: 2n * 10n ** 18n,
});decodeRgemInitParams(...)
Decodes RGEM modelData back into typed runtime values.
getReadableContractError(...)
Converts revert data from the auction and gacha contracts into more readable messages.
try {
await contracts.auction.placeBid({
auctionId: 1n,
bidAmount: 1n,
maxBidFee: 0n,
});
} catch (error) {
console.error(getReadableContractError(error));
}encodeFileParamName(...)
Encodes a string config key like "paused" into bytes32 for file(...)
calls. If a hex value is already provided, it passes through unchanged.
Backwards-Compatible Wrapper
createLateralSdk(...) remains available for older consumers:
const sdk = createLateralSdk({
baseUrl,
contracts: {
publicClient,
walletClient,
chainId: 11155111,
},
seaport: {
walletClient,
},
});
await sdk.api.getHealth();
await sdk.contracts?.auction.getAuctionDetails({ auctionId: 1n });
await sdk.seaport?.getCounter();New code should prefer createLateralApiClient(...) and
createLateralContractsClient(...) / createLateralSeaportClient(...)
directly.
Validation
The SDK is validated in apps/sdk-e2e.
Useful commands:
pnpm -C packages/sdk build
pnpm -C apps/sdk-e2e test
pnpm -C apps/sdk-e2e test:gacha:forkThe Sepolia auction tests cover the live auction flow. The Anvil fork suite covers the deployed Sepolia gacha stack in more depth.
