# swap:safe — Ammora SDK 0.3.8 Executes the preferred wallet-facing exact-input flow: reviewed pool, revision-correct quote, exact approval, receipt-block simulation, swap, and receipt-block output reconciliation. npm run swap:safe -- [native] [Read in Docs](https://docs.ammora.org/examples?command=swap%3Asafe) · [Detailed guide](https://docs.ammora.org/guides/src-arl-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 swap:safe -- ` (`tsx src/arl/safe-swap.ts`). Omit `--` and arguments when the source accepts none. ## Entry file: `src/arl/safe-swap.ts` ```typescript /** * Executes the preferred wallet-facing exact-input flow: reviewed pool, * revision-correct quote, exact approval, receipt-block simulation, swap, and * receipt-block output reconciliation. * * npm run swap:safe -- [native] */ import { tokenAmount, slippage } from "../shared/input.js"; import { describeSwapStatus } from "../shared/status.js"; import { AmmoraSwapClient, type AmmoraSwapModel, } from "@ammora-protocol/sdk"; import { deployment, address, explorerLink, reader, signer } from "../shared/env.js"; import { amount, main, requireContract, tokenInfo } from "../shared/run.js"; const models = new Set([ "almm", "concentrated", "compounding", "dbc", ]); main(async () => { const [modelArgument, poolArgument, tokenArgument, amountArgument, inputAssetArgument] = process.argv.slice(2); if (!models.has(modelArgument as AmmoraSwapModel)) { throw new Error("model must be almm, concentrated, compounding, or dbc"); } if (!amountArgument) throw new Error("amountIn is required"); if (inputAssetArgument && inputAssetArgument !== "native") { throw new Error("the optional fifth argument must be native"); } const model = modelArgument as AmmoraSwapModel; const pool = address("POOL", poolArgument); const tokenIn = address("TOKEN_IN", tokenArgument); const { wallet, account } = signer(); const client = await reader(); await Promise.all([ requireContract(client, "pool", pool), requireContract(client, "input token", tokenIn), ]); const input = await tokenInfo(client, tokenIn); const amountIn = tokenAmount(amountArgument, input.decimals); const swaps = await AmmoraSwapClient.create(client, { deploymentCatalog: { [deployment().chain.id]: deployment() } }); const prepared = await swaps.prepareExactIn({ model, pool, tokenIn, inputAsset: inputAssetArgument === "native" ? "native" : "erc20", amountIn, payer: account.address, recipient: account.address, slippageBps: slippage(), executionMode: "direct-wallet", }); const output = await tokenInfo(client, prepared.quote.tokenOut); console.log(`model ${model}`); console.log(`pay ${amount( amountIn, input.decimals, inputAssetArgument === "native" ? "ETH" : input.symbol, )}`); console.log(`approval ${prepared.approvalRequirements.length === 0 ? "not required" : "required"}`); console.log(`receive ${amount( prepared.quote.expectedAmountOut, output.decimals, output.symbol, )} estimated`); console.log(`minimum ${amount( prepared.quote.minimumAmountOut, output.decimals, output.symbol, )}`); console.log(`quote block ${prepared.quote.quoteBlockNumber}`); const result = await prepared.execute(wallet, { onStatus: (status) => console.log(` ${describeSwapStatus(status)}`), }); console.log(`transaction ${explorerLink(result.hash)}`); console.log(result.amountReceived === null ? "received receipt-block balance verification unavailable" : `received ${amount(result.amountReceived, output.decimals, output.symbol)} verified`); }); ``` ## 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/shared/status.ts](https://docs.ammora.org/examples/source/src/shared/status.ts.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.