# almm:seed-liquidity — Ammora SDK 0.3.8 Check the source for arguments and transaction requirements. [Read in Docs](https://docs.ammora.org/examples?command=almm%3Aseed-liquidity) · [Detailed guide](https://docs.ammora.org/guides/src-almm-readme) · [Local setup](https://docs.ammora.org/guides/example-setup) ## Context and execution GIWA Sepolia 91342. Public SDK 0.3.8, Math 0.3.0. Source revision: `a9b3fd798fa51495e8defec99a25de59e4d70672`. Install the SDK in your app, or prepare the example project using the local setup guide for its npm commands. Review the entry source and guide for required arguments, roles and deployment selection. `AMMORA_SEND=0` does not turn send-only commands into previews. Never put CLI keys in a browser or resend an uncertain transaction. Command: `npm run almm:seed-liquidity -- ` (`tsx src/almm/seed-liquidity.ts`). Omit `--` and arguments when the source accepts none. ## Entry file: `src/almm/seed-liquidity.ts` ```typescript import { tokenAmount } from "../shared/input.js"; /** * Seed a bin pool from one side, spread across a range. * * npm run almm:seed-liquidity -- * * Seeding funds a range from a single token and hands the position an operator and a fee * owner, which is the shape a launch uses to place its own liquidity. The caller must be the * operator, which the SDK checks before planning anything. */ import { parseEventLogs, zeroAddress } from "viem"; import { ALMMClient } from "@ammora-protocol/sdk"; import { clientOptions, address, deployment, reader, signer } from "../shared/env.js"; import { amount, approve, asPool, main, requireContract, send, tokenInfo } from "../shared/run.js"; const erc721TransferAbi = [{ type: "event", name: "Transfer", inputs: [ { indexed: true, name: "from", type: "address" }, { indexed: true, name: "to", type: "address" }, { indexed: true, name: "tokenId", type: "uint256" }, ], }] as const; main(async () => { const [poolArgument, sideArgument, amountArgument, lowerArgument, upperArgument] = process.argv.slice(2); const pool = address("ALMM_POOL", poolArgument); if (sideArgument !== "base" && sideArgument !== "quote") { throw new Error("usage: "); } if (!amountArgument || !lowerArgument || !upperArgument) { throw new Error("usage: "); } const lowerBinId = Number(lowerArgument); const upperBinId = Number(upperArgument); if (!Number.isInteger(lowerBinId) || !Number.isInteger(upperBinId) || upperBinId < lowerBinId) { throw new Error("bin ids must be whole numbers with upper at or above lower"); } const { wallet, account } = signer(); const client = await reader(); const contracts = deployment().contracts.liquidityMarketMaker; await requireContract(client, "pool", pool); const sdk = new ALMMClient(client, pool, contracts.positionManager, contracts.binLens, clientOptions()); const state = await asPool(pool, "a bin pool", () => sdk.getPoolState()); const [base, quote] = await Promise.all([ tokenInfo(client, state.baseToken), tokenInfo(client, state.quoteToken), ]); const side = sideArgument === "base" ? base : quote; console.log(`pool ${pool}`); console.log(`seeding ${amount(tokenAmount(amountArgument, side.decimals), side.decimals, side.symbol)}`); console.log(`range bins ${lowerBinId} .. ${upperBinId}`); console.log(""); const plan = await sdk.planSeedLiquidity({ lowerBinId, upperBinId, tokenSide: sideArgument, amount: tokenAmount(amountArgument, side.decimals), strategy: 0, shareSlippageBps: 100, maxActiveBinSlippage: 5, recipient: account.address, // Who collects the position's fees, and who may operate it. Seeding exists so those // can differ from the owner; here they are all the caller. feeOwner: account.address, operator: account.address, caller: account.address, lockReleasePoint: 0n, deadline: BigInt(Math.floor(Date.now() / 1000) + 600), }); await approve(plan.approvalRequirements, wallet, account, client); const hash = await send("seedLiquidity", plan.transaction, wallet, account, client); const receipt = await client.getTransactionReceipt({ hash }); const minted = parseEventLogs({ abi: erc721TransferAbi, eventName: "Transfer", logs: receipt.logs, }).find((log) => log.address.toLowerCase() === contracts.positionManager.toLowerCase() && log.args.from === zeroAddress && log.args.to.toLowerCase() === account.address.toLowerCase() ); if (!minted) throw new Error("seed receipt contains no manager mint event"); console.log(` position token id: ${(minted.args as { tokenId: bigint }).tokenId}`); }); ``` ## Supporting files Keep relative paths intact. Local imports are listed recursively; JSON templates are choices to review, not approved inputs. Runtime-selected files and wallet/environment setup still follow the detailed guide. - [src/shared/env.ts](https://docs.ammora.org/examples/source/src/shared/env.ts.txt) - [src/shared/input.ts](https://docs.ammora.org/examples/source/src/shared/input.ts.txt) - [src/shared/retry.ts](https://docs.ammora.org/examples/source/src/shared/retry.ts.txt) - [src/shared/rpc.ts](https://docs.ammora.org/examples/source/src/shared/rpc.ts.txt) - [src/shared/run.ts](https://docs.ammora.org/examples/source/src/shared/run.ts.txt) - [src/almm/rebalance.example.json](https://docs.ammora.org/examples/source/src/almm/rebalance.example.json.txt) - [package.json](https://docs.ammora.org/examples/source/package.json.txt) - [package-lock.json](https://docs.ammora.org/examples/source/package-lock.json.txt) - [tsconfig.json](https://docs.ammora.org/examples/source/tsconfig.json.txt) - [.env.giwa.example](https://docs.ammora.org/examples/source/file.env.giwa.example.txt) - [.nvmrc](https://docs.ammora.org/examples/source/file.nvmrc.txt) ## AI implementation checklist Use the actual SDK exports and parameter types in the linked files. Start with reads and unsigned plans where supported. Use a connected wallet for browser signing. Preserve raw integer units, exact approvals, caller authority, deadlines and receipt reconciliation. Report local checks separately from live-chain verification.