@cypherindustries/factory-sdk
v1.3.3
Published
TypeScript SDK for the Cypher Factory bonding curve launchpad — deploy, trade, graduate, stake, and manage tokens programmatically
Maintainers
Readme
@cypherindustries/factory-sdk
TypeScript SDK for the Cypher Factory bonding curve launchpad. Deploy tokens, trade on bonding curves, trigger graduations, stake, manage referrals, and more -- all programmatically or through AI agent frameworks.
Requirements
- Node.js >= 24
Installation
npm install @cypherindustries/factory-sdkQuick Start
import { LaunchpadAgent, ToolExecutor } from "@cypherindustries/factory-sdk";
import { WalletManager } from "@cypherindustries/factory-sdk/wallet";
// Resolve wallet: keystore (recommended) -> env var -> auto-generate
const walletMgr = new WalletManager();
const { wallet, source } = await walletMgr.resolve({
keystorePassword: process.env.CYPHER_KEYSTORE_PASSWORD,
});
// Initialize the agent
const agent = new LaunchpadAgent({
privateKey: wallet.privateKey,
rpcUrl: process.env.RPC_URL!,
factoryAddress: "0x...",
bondingCurveAddress: "0x...",
});
// Direct usage
const state = await agent.getTokenState("0xTOKEN...");
console.log(`${state.name}: ${state.pricePerToken} wei per token`);
const result = await agent.buy("0xTOKEN...", "0.5"); // Buy with 0.5 ETH
console.log(`Bought ${result.amount} tokens`);
// Or use the ToolExecutor for LLM agent integration
const tools = new ToolExecutor(agent);
const buyResult = await tools.execute("buy_token", {
token_address: "0xTOKEN...",
eth_amount: "0.5",
});For the full tool reference across all integration paths, see API-REFERENCE.md.
Configuration
The agent supports flexible configuration with sensible defaults:
import { LaunchpadAgent, createDefaultConfig } from "@cypherindustries/factory-sdk";
const agent = new LaunchpadAgent(
{
privateKey: wallet.privateKey,
rpcUrl: process.env.RPC_URL!,
factoryAddress: "0x...",
bondingCurveAddress: "0x...",
highlightsManagerAddress: "0x...",
referralManagerAddress: "0x...",
vestingAddress: "0x...",
pluginFactoryAddress: "0x...",
// Optional UX/integration overrides
apiBaseUrl: "https://api.factory.cyphereth.com",
explorerBaseUrl: "https://etherscan.io",
referralBaseUrl: "https://factory.cyphereth.com",
referrerAddress: "0x...",
},
{
trading: {
defaultSlippageBps: 300, // 3% slippage
maxTradeETH: "1.0", // Max 1 ETH per trade
gasReserve: "0.05", // Keep 0.05 ETH for gas
autoApprove: true, // Auto-approve tokens before selling
},
risk: {
stopLossPct: 30, // 30% stop loss
takeProfitPct: 200, // 200% take profit
maxOpenPositions: 20,
},
ops: {
dryRun: false, // Set true to simulate without executing
logging: true,
},
}
);
// Update config at runtime
agent.setTrading({ defaultSlippageBps: 500 });
agent.setOps({ dryRun: true });Configuration Options
| Option | Type | Description |
|--------|------|-------------|
| apiBaseUrl | string | REST API base URL for token queries and image upload |
| explorerBaseUrl | string | Block explorer base URL for transaction links |
| referralBaseUrl | string | Referral link base URL |
| referrerAddress | string | Default referrer address for affiliate tracking |
| algebraSwapRouterAddress | string | Algebra V4 SwapRouter — used post-graduation for pool_swap |
| algebraQuoterAddress | string | Algebra V4 QuoterV2 — used for quote_pool_swap |
| algebraFactoryAddress | string | Algebra V4 pool factory — used to validate pool authenticity |
| algebraNftPositionManagerAddress | string | Algebra V4 NonfungiblePositionManager — used for default-pool LP add/remove/collect |
Core Features
Upload Images
Token images are uploaded via the REST API:
// Upload a local image via API
const imageUrl = await agent.uploadImage("./my-token-image.png");
// Returns: "https://api.factory.cyphereth.com/uploads/..."Deploy Tokens
const { txHash, tokenAddress } = await agent.deploy({
name: "My Token",
symbol: "MTK",
description: "A great token",
image: imageUrl,
communityFeeRatio: 50,
salt: "unique-salt",
socialLinks: {
twitter: "https://x.com/mytoken",
telegram: "https://t.me/mytoken",
website: "https://mytoken.xyz",
},
stakingConfig: {
deployStaking: true, // Staking vault on by default
alternativeFeeRecipient: "0x...",
},
});
// Staking vault deployed by default. Pass skipStakingVault: true to opt out.Buy and Sell
// Buy tokens with ETH
const buyResult = await agent.buy("0xTOKEN...", "0.5", {
slippageBps: 300,
affiliate: "0xAFFILIATE...",
});
// Response includes fee decomposition: protocolFee, creatorFee, referralFee
// Sell tokens for ETH
const sellResult = await agent.sell("0xTOKEN...", "1000");
// Get quotes without executing (CurveMath exact calculations)
const buyQuote = await agent.quoteBuy("0xTOKEN...", "0.5");
const sellQuote = await agent.quoteSell("0xTOKEN...", "1000");Check Token State
const state = await agent.getTokenState("0xTOKEN...");
console.log({
name: state.name,
price: state.pricePerToken,
tvl: state.tvl,
isGraduated: state.isLPd,
graduationFees: state.graduationFees,
protocolFee: state.protocolFee, // Fee decomposition
});Graduation
// Check how close a token is to graduating (auto-graduation detection)
const estimate = await agent.estimateGraduation("0xTOKEN...");
console.log(`ETH needed: ${estimate.ethNeeded}, Caller fee: ${estimate.callerFeeETH}`);
// Trigger graduation (if close enough)
const result = await agent.triggerGraduation("0xTOKEN...");Post-Graduation Trading (Algebra V4)
Once a token has graduated, it trades on an Algebra Integral V4 pool with a custom AlgebraFeePlugin. The SDK exposes both direct pool access and transparent auto-routing through the existing buy/sell methods.
// Direct pool quote -- off-chain via QuoterV2
// Provide exactly one of amountIn (exact-input) or amountOut (exact-output).
const quoteIn = await agent.quotePoolSwap({
tokenAddr: "0xTOKEN...",
side: "buy",
amountIn: "0.1", // spend exactly 0.1 ETH
});
const quoteOut = await agent.quotePoolSwap({
tokenAddr: "0xTOKEN...",
side: "buy",
amountOut: "1000", // receive exactly 1000 tokens
});
console.log(quoteIn.mode, quoteIn.amountOut); // 'exact_input', simulated tokens out
console.log(quoteOut.mode, quoteOut.amountIn); // 'exact_output', required ETH in
// Direct pool swap -- both modes supported. Pre-quotes via QuoterV2 every time
// (matches the BC pattern), then applies slippage to the unspecified side.
const swapIn = await agent.poolSwap({
tokenAddr: "0xTOKEN...",
side: "buy",
amountIn: "0.1",
slippageBps: 200,
});
const swapOut = await agent.poolSwap({
tokenAddr: "0xTOKEN...",
side: "buy",
amountOut: "1000", // receive exactly 1000 tokens, refund unused ETH
slippageBps: 200,
});
console.log(swapOut.mode, swapOut.amountIn, swapOut.amountOut, swapOut.path);
// Or just keep calling buy()/sell() -- they auto-route post-graduation
const result = await agent.buy("0xTOKEN...", "0.1");
console.log(result.path); // 'bonding-curve' before graduation, 'algebra-pool' after
// getTokenState includes a pool block once isLPd === true
const state = await agent.getTokenState("0xTOKEN...");
if (state.pool) {
console.log({
pool: state.pool.address,
feeReceiver: state.pool.feeReceiver,
stakingVault: state.pool.stakingVault,
currentFeeBps: state.pool.currentFeeBps,
});
}Fees auto-route — there is no claim flow. The AlgebraFeePlugin forwards
each swap's fees to feeReceiver and the staking vault synchronously
inside the swap, weighted by communityFeeRatio. Recipients never
accumulate pending balances. The protocol's Harvester contract operates
on protocol-owned liquidity only and is intentionally not exposed via the
SDK.
Default-Pool LP Management (Algebra V4)
Two distinct pools exist for a graduated token's pair:
- Custom-deployer pool (the protocol's pool) — every swap fee routes
to
AlgebraFeePlugin.feeReceiverand the staking vault. LPing here earns nothing. - Default-deployer pool (
deployer === address(0)) — vanilla Algebra V4. Swap fees accrue per-position viafeeGrowthInside*and require an explicitcollect()to harvest. This is the pool the LP-management methods operate on.
// Mint a new full-range LP position. Atomically creates the default pool
// at the protocol pool's current sqrtPriceX96 if it doesn't exist yet.
const add = await agent.addLiquidity({
tokenAddr: "0xTOKEN...",
amountEthMax: "0.1",
amountTokenMax: "1000",
tickPreset: "full", // 'full' (default) | 'narrow' (~±5%) | 'wide' (~±25%)
slippageBps: 200,
});
console.log(add.positionTokenId, add.createdPool); // tokenId, true if pool was just created
// Increase liquidity on an existing position
const inc = await agent.addLiquidity({
tokenAddr: "0xTOKEN...",
amountEthMax: "0.05",
amountTokenMax: "500",
positionTokenId: add.positionTokenId,
});
// Harvest fees without changing position size
// (required — default-pool fees do NOT auto-transfer)
const fees = await agent.collectFees({
positionTokenId: add.positionTokenId,
unwrapWeth: true,
});
console.log(fees.amount0, fees.amount1);
// Withdraw 50% (no burn)
const partial = await agent.removeLiquidity({
positionTokenId: add.positionTokenId,
liquidityPct: 50,
});
// Withdraw 100% and burn the NFT (default behavior at 100%)
const full = await agent.removeLiquidity({
positionTokenId: add.positionTokenId,
liquidityPct: 100,
});
console.log(full.burned); // true
// Enumerate the wallet's NPM positions (filter by deployer for default-pool)
const positions = await agent.getLpPositions();
const defaultPoolPositions = positions.filter(
(p) => p.deployer.toLowerCase() === "0x0000000000000000000000000000000000000000"
);createAndInitializePoolIfNecessary is idempotent — repeated addLiquidity
calls don't re-create the pool. removeLiquidity bundles
decreaseLiquidity → collect → [unwrapWNativeToken+sweepToken] → [burn] in
a single multicall; collectFees is multicall(decreaseLiquidity(0), collect, [unwrap+sweep]).
Staking
// Look up staking vault for a token (requires pluginFactoryAddress)
const vaultAddr = await agent.getStakingVaultAddress("0xTOKEN...");
// Get staking position details
const position = await agent.getStakingPosition(vaultAddr);
console.log(`Shares: ${position.shares}, Assets: ${position.assets}`);
// Stake tokens
await agent.stake(vaultAddr, "0xTOKEN...", "1000");
// Request unstake by asset amount (starts cooldown)
await agent.requestUnstake(vaultAddr, "500");
// Or request unstake by share amount
await agent.requestUnstakeByShares(vaultAddr, "250");
// Complete unstake after cooldown
const status = await agent.getCooldownStatus(vaultAddr);
if (status.isReady) {
await agent.completeUnstake(vaultAddr);
}API Queries
Query token data from the REST API:
// Get token list with pagination
const tokens = await agent.getTokenList({ page: 1, limit: 20 });
// Get token holder distribution
const distribution = await agent.getTokenDistribution("0xTOKEN...");
// Get user's token holdings (defaults to agent wallet)
const holdings = await agent.getUserHoldings();
// Get tokens created by a user
const creations = await agent.getUserCreations("0xWALLET...");Strategy Management
Manage automated trading strategies via tools:
// Start a strategy (requires wss:// RPC URL)
await tools.execute("start_strategy", {
strategy_name: "launch_sniper",
config: { ethAmount: "0.1", maxSlippageBps: 500 },
});
// Check strategy status
const status = await tools.execute("get_strategy_status", {
strategy_name: "launch_sniper",
});
// List available strategies
const strategies = await tools.execute("list_available_strategies", {});
// Stop a running strategy
await tools.execute("stop_strategy", { strategy_name: "launch_sniper" });Referral Links
// Generate a referral link for a token
const link = await tools.execute("generate_referral_link", {
token_address: "0xTOKEN...",
});Event Subscriptions
agent.onNewCoin(({ token, name, symbol, price }) => {
console.log(`New token: ${name} (${symbol}) at ${token}`);
});
agent.onBuy(({ buyer, token, ethAmount, tokenAmount }) => {
console.log(`Buy: ${buyer} bought ${tokenAmount} tokens`);
});
agent.onGraduation(({ token, lp }) => {
console.log(`Graduated: ${token} -> LP at ${lp}`);
});Security Features
Chain-ID Verification
Every write operation is gated on a one-time provider.getNetwork() check
against ConnectionConfig.expectedChainId (default: Ethereum Mainnet —
1). If the RPC URL points at the wrong chain, the first buy,
sell, deploy, or triggerGraduation call throws
SecurityValidationError('CHAIN_ID_MISMATCH') before any transaction is
submitted. The check is memoized, so production hot paths pay for exactly
one extra RPC round-trip per agent lifetime.
// Default: pinned to Ethereum Mainnet (1).
const agent = new LaunchpadAgent({ ...conn });
// Pin to a different chain:
const agent = new LaunchpadAgent({ ...conn, expectedChainId: 42161 });
// Opt out (local forks / Anvil only — unsafe in production):
const agent = new LaunchpadAgent({ ...conn, expectedChainId: null });
// Manual verification (useful for health checks):
await agent.ensureChainId();Keystore Wallet (Default)
The SDK defaults to encrypted keystore storage (AES-256-GCM with scrypt KDF):
import { WalletManager } from "@cypherindustries/factory-sdk/wallet";
const walletMgr = new WalletManager();
const { wallet, source } = await walletMgr.resolve({
keystorePassword: process.env.CYPHER_KEYSTORE_PASSWORD,
});
// source: 'keystore' | 'env' | 'auto-generated'
// Keystore saved to ~/.cypher-factory/agent-wallet.encPrompt Injection Detection
Freeform text fields (token name, description, symbol) are automatically scanned for prompt injection attempts before tool execution.
Adaptive Rate Limiting
Per-endpoint rate limiting with automatic backoff and queue draining. Prevents RPC throttling and ensures fair usage.
Pre-flight Checks
Write transactions go through static call simulation to catch reverts before spending gas.
AI Agent Integration
ToolExecutor
The SDK provides a ToolExecutor for easy integration with LLM agent frameworks:
import { ToolExecutor, TOOL_DEFINITIONS } from "@cypherindustries/factory-sdk";
import { TxGate } from "@cypherindustries/factory-sdk/tx-gate";
// Basic usage (no spending limits)
const tools = new ToolExecutor(agent);
// With TxGate for spending limits (recommended for LLM agents)
const gate = new TxGate({ maxPerTxETH: "1.0", dailyBudgetETH: "5.0" });
const tools = new ToolExecutor(agent, { gate });
// With tool name prefix (e.g. for OpenClaw: "cypher_buy_token")
const tools = new ToolExecutor(agent, { gate, toolPrefix: "cypher_" });
// Get tool schemas (for registering with your LLM)
const schemas = tools.getTools(); // Returns 64 tool definitions
// Execute tool calls from your LLM
const result = await tools.execute("buy_token", {
token_address: "0x...",
eth_amount: "0.5",
});
// Write ops are auto-gated: checked before execution, recorded after success
// OpenAI function calling format
const openAITools = tools.getToolsAsOpenAIFunctions();Each tool has a category field ("read", "write", "config") that determines TxGate behavior. Write operations are automatically checked against spending limits before execution.
For the complete tool reference, see API-REFERENCE.md.
MCP Server
For Claude Code, Cursor, Windsurf, and other MCP-compatible clients, use the companion MCP server:
npx @cypherindustries/factory-mcp-serverSee @cypherindustries/factory-mcp-server for setup instructions.
Strategies (Optional)
Pre-built trading strategies for automated bots:
import { StrategyRunner, LaunchSniper, CopyTrader, ExitMonitor } from "@cypherindustries/factory-sdk";
const runner = new StrategyRunner(agent);
runner
.use(new LaunchSniper()) // Snipe new launches
.use(new CopyTrader()) // Copy whale trades
.use(new ExitMonitor()); // Auto stop-loss/take-profit
await runner.start();Transaction Gate (Security)
Security layer for spending limits. When used with ToolExecutor, write
operations are auto-gated. In strategies, the gate's confirmation callback
is wrapped by a 20-second hard timeout (CONFIRM_TIMEOUT_MS) so a hanging
confirmFn cannot starve the reservation budget — a timeout is treated
identically to a decline:
import { TxGate } from "@cypherindustries/factory-sdk/tx-gate";
import { ToolExecutor } from "@cypherindustries/factory-sdk";
const gate = new TxGate({
maxPerTxETH: "1.0", // Max 1 ETH per transaction
dailyBudgetETH: "5.0", // Rolling 24h budget
cooldownSeconds: 5, // Min seconds between writes
confirmAboveETH: "0.5", // Ask confirmation above 0.5 ETH
});
// Pass gate to ToolExecutor -- write ops are auto-checked and recorded
const tools = new ToolExecutor(agent, { gate });
// Or use standalone for manual gating
const reservation = gate.reserve("buy_token", ethers.parseEther("0.5"));
if (reservation.allowed) {
// Execute trade, then commit the reservation
gate.commit(reservation.id, "buy_token", ethers.parseEther("0.5"));
}
// Check spending stats
const stats = gate.getStats();
// { spent24h: '0.5', remaining24h: '4.5', txCount24h: 1, ... }Wallet Management
import { WalletManager } from "@cypherindustries/factory-sdk/wallet";
const walletManager = new WalletManager();
// Resolves wallet from: keystore -> env var -> generate new
const { wallet, source } = await walletManager.resolve({
keystorePassword: process.env.CYPHER_KEYSTORE_PASSWORD,
privateKey: process.env.CYPHER_PRIVATE_KEY,
});Advanced Modules
The SDK exports several advanced modules for building custom agent architectures. These are not part of the primary tool interface -- they are lower-level building blocks used internally by LaunchpadAgent and exposed for advanced integrators who need fine-grained control.
Provider Abstraction
import { EthersProviderAdapter, EthersSignerAdapter } from "@cypherindustries/factory-sdk";
import type { ProviderAdapter, SignerAdapter } from "@cypherindustries/factory-sdk";ProviderAdapter and SignerAdapter wrap ethers.js provider/signer types, providing a stable interface for future migration to alternative Web3 libraries.
Composition Components
import {
ContractManager, // Contract caching + Multicall3 batched RPC reads
EventBus, // Event subscription and listener lifecycle management
WebSocketManager, // WebSocket reconnection with exponential backoff
} from "@cypherindustries/factory-sdk";These are extracted from LaunchpadAgent for reuse in custom agent compositions.
Order Splitting
import { OrderSplitter, DEFAULT_ORDER_SPLITTER_CONFIG } from "@cypherindustries/factory-sdk";
import type { OrderSplitterConfig, SplitResult } from "@cypherindustries/factory-sdk";OrderSplitter breaks large bonding curve trades into liquidity-aware chunks with binary-search slippage optimization. Opt-in via ConnectionConfig.orderSplitter.
State Persistence
import { JSONFileBackend, CURRENT_STATE_VERSION } from "@cypherindustries/factory-sdk";
import type { StateBackend, PersistedState } from "@cypherindustries/factory-sdk";StateBackend is a pluggable interface for saving/loading agent state across restarts. JSONFileBackend provides atomic file writes with versioned state.
Transaction Queue
import { TransactionQueue, executeWithRetry } from "@cypherindustries/factory-sdk";
import type { RetryPolicy, DeadLetterEntry } from "@cypherindustries/factory-sdk";TransactionQueue serializes on-chain transactions with async-mutex, per-error-type retry policies, and a dead-letter queue for failed transactions.
Dry-Run Results
import { isDryRunResult, createDryRunResult } from "@cypherindustries/factory-sdk";
import type { DryRunResult } from "@cypherindustries/factory-sdk";DryRunResult is a typed return object replacing the legacy '0x_dry_run' magic string. Use isDryRunResult() for type-safe detection.
Multicall3
import {
multicallBatch,
MULTICALL3_ADDRESS,
MULTICALL_FALLBACK_CALL_TIMEOUT_MS,
} from "@cypherindustries/factory-sdk";Batch multiple RPC read calls into a single Multicall3.aggregate3 call
with automatic per-call failure handling. The fallback path (used when
Multicall3 is unavailable at the RPC) races each individual call against a
10-second timeout so a single stuck request cannot stall the batch.
Bigint-Safe JSON
import { safeJsonStringify, jsonReplacer } from "@cypherindustries/factory-sdk";
// Drop-in for JSON.stringify that handles bigint fields.
safeJsonStringify({ wei: 1_234_567_890_000_000_000n });
// → '{"wei":"1234567890000000000"}'JSON.stringify throws TypeError on any bigint value, so objects that
embed wei amounts (e.g. TxGate.getStats()) cannot be serialized
directly. safeJsonStringify preserves the native
JSON.stringify(value, replacer, space) signature and coerces bigint
values to decimal strings in a single pass, composing cleanly with any
caller-supplied replacer.
Persisted State Validation
import { validatePersistedState } from "@cypherindustries/factory-sdk";Runtime schema check applied by LaunchpadAgent.loadState() to every
persisted state file. Rejects prototype-polluting keys (__proto__,
constructor, prototype), wrong-typed fields, and unparseable bigint
strings. Exported so integrators with custom backends can run the same
validation before handing data back to the agent.
Sub-path Exports
Import specific modules for smaller bundles:
import { LaunchpadAgent } from "@cypherindustries/factory-sdk";
import { TOOL_DEFINITIONS } from "@cypherindustries/factory-sdk/tools";
import { StrategyRunner } from "@cypherindustries/factory-sdk/strategies";
import { TxGate } from "@cypherindustries/factory-sdk/tx-gate";
import { WalletManager } from "@cypherindustries/factory-sdk/wallet";
import { FACTORY_ABI, BONDING_CURVE_ABI } from "@cypherindustries/factory-sdk/abis";Default Contract Addresses (Ethereum Mainnet)
The SDK includes default addresses for Ethereum Mainnet. These are used automatically if no custom addresses are provided:
| Contract | Address |
|----------|---------|
| BCTokenFactory | 0x5145e18526b6851f9e6aa28f11cb667956aa0920 |
| BondingCurve | 0x035d264b16d445eb6a5b3109a40224e210035245 |
| HighlightsManager | 0x6ef6dec7a077f68424e23f090d5fd57e01415e35 |
| ReferralManager | 0x4e06b03a4a84fea63c565cd0e47747f8cb88f773 |
| TokenVesting | 0x3590194aaf1dbf5923bd5a4e69f2ada90c94b348 |
| AlgebraFeePluginFactory | 0x478dc624b9cfb68ed1cea0e7b51a6279905f7fb3 |
| StakingVaultFactory | 0xb4a217606603f68dc18ec88b8622464c4c90aa55 |
| LiquidityManager | 0x14127323b4b84e9688ef1018ab5f641344aa07dc |
| Harvester | 0x59716fb1d8a2131c1cab3847842fd6c8583f3681 |
| BCTokenDeployer | 0xe5a1438aca8e48a0d6ef6fc402254b709ec67d79 |
| CurveMath | 0x78e6b8e6f479323fbbeb31878c1538c270199e32 |
| WETH | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
Default RPC: wss://ethereum-rpc.publicnode.com (public endpoint; use your own for production)
import { DEFAULT_CONNECTION_CONFIG, ETHEREUM_MAINNET_ADDRESSES } from "@cypherindustries/factory-sdk";
// Use defaults directly
const agent = new LaunchpadAgent({
privateKey: wallet.privateKey,
...DEFAULT_CONNECTION_CONFIG,
});
// Or access individual addresses
console.log(ETHEREUM_MAINNET_ADDRESSES.BondingCurve);Environment Variables
Environment variables can override the defaults:
# Wallet (keystore recommended for production)
CYPHER_KEYSTORE_PASSWORD=your-strong-password
CYPHER_PRIVATE_KEY=0x... # Alternative: raw private key
# RPC (optional - defaults to Ethereum Mainnet public node)
CYPHER_RPC_URL=wss://...
# Contract addresses (optional - defaults to Ethereum Mainnet)
CYPHER_FACTORY_ADDRESS=0x...
CYPHER_BONDING_CURVE_ADDRESS=0x...
CYPHER_HIGHLIGHTS_ADDRESS=0x...
CYPHER_REFERRAL_ADDRESS=0x...
CYPHER_VESTING_ADDRESS=0x...
CYPHER_PLUGIN_FACTORY_ADDRESS=0x...
CYPHER_CURVE_MATH_ADDRESS=0x...
# Optional UX/integration overrides
CYPHER_API_BASE_URL=https://api.factory.cyphereth.com
CYPHER_EXPLORER_URL=https://etherscan.io
CYPHER_REFERRAL_BASE_URL=https://factory.cyphereth.com
CYPHER_REFERRER_ADDRESS=0x...Changes
See CHANGELOG.md for release notes. Latest: v1.3.3 — docs audit / README refresh (see also v1.3.2 for the Algebra V4 default-pool LP management surface).
Development
Standalone
cd packages/sdk
pnpm install
pnpm build
pnpm typecheckFrom Monorepo Root
git clone https://github.com/CypherIndustries/factory-agent-sdk
cd factory-agent-sdk
pnpm install
pnpm build:sdkLicense
MIT
