# dfs:position-permission — Ammora SDK 0.3.8 dfs:position-permission -- . Exact fee/reward bits only. Concentrated uses Manager NFTs; raw NFT approval is a broader, separate operation. [Read in Docs](https://docs.ammora.org/examples?command=dfs%3Aposition-permission) · [Detailed guide](https://docs.ammora.org/guides/src-dfs-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 dfs:position-permission -- ` (`tsx src/dfs/position-permission.ts`). Omit `--` and arguments when the source accepts none. ## Entry file: `src/dfs/position-permission.ts` ```typescript /** dfs:position-permission -- . * Exact fee/reward bits only. Concentrated uses Manager NFTs; raw NFT approval is a broader, separate operation. */ import { ammConcentratedPositionManagerV3Abi, ammCompoundingPoolV3Abi, buildUpdateManagedAmmDelegatePermission, buildUpdateCompoundingDelegatePermission } from "@ammora-protocol/sdk"; import { zeroAddress } from "viem"; import { dfs } from "./context.js"; import { sourcePermission } from "./source-policy.js"; import { arl, natural, execute } from "../shared/actions.js"; import { v4Deployment } from "../shared/env.js"; import { main } from "../shared/run.js"; import { printJson } from "../shared/input.js"; main(async () => { const [vault, pool, kind, id, mode, ...extra] = process.argv.slice(2); if (extra.length || !["concentrated", "compounding"].includes(kind ?? "")) throw new Error("Select a pool kind and exact fee/reward/revoke mode"); const permission = sourcePermission(mode); const d = await dfs(vault), c = await arl(pool, kind as "concentrated" | "compounding"), tokenId = natural(id, "nftId"); const target = kind === "concentrated" ? v4Deployment().contracts.launch.concentratedPositionManager : c.pool; const abi = kind === "concentrated" ? ammConcentratedPositionManagerV3Abi : ammCompoundingPoolV3Abi; const owner = await c.client.readContract({ address: target, abi, functionName: "ownerOf", args: [tokenId] }); if (owner.toLowerCase() !== c.caller.toLowerCase()) throw new Error("Only actual NFT owner may configure DFS permissions"); if (kind === "concentrated") { const p = await c.client.readContract({ address: target, abi: ammConcentratedPositionManagerV3Abi, functionName: "getPosition", args: [tokenId] }); if (p.pool.toLowerCase() !== c.pool.toLowerCase()) throw new Error("Manager NFT belongs to another pool"); } const previous = await c.client.readContract({ address: target, abi, functionName: "positionDelegate", args: [tokenId] }); const previousPermission = await c.client.readContract({ address: target, abi, functionName: "delegatePermission", args: [tokenId] }); if (previous !== zeroAddress && previous.toLowerCase() !== d.vault.toLowerCase()) throw new Error("Another delegate exists; do not replace its slot implicitly"); const delegate = permission ? d.vault : zeroAddress; const call = kind === "concentrated" ? buildUpdateManagedAmmDelegatePermission(tokenId, delegate, permission) : buildUpdateCompoundingDelegatePermission(tokenId, delegate, permission); printJson({ target, tokenId, previous, previousPermission, delegate, permission, note: "Replaces the single slot with EXACT bits; no principal/NFT-transfer permission" }); await execute("set DFS fee/reward position permission", c, { to: target, ...call }); }); ``` ## 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/dfs/context.ts](https://docs.ammora.org/examples/source/src/dfs/context.ts.txt) - [src/dfs/source-policy.ts](https://docs.ammora.org/examples/source/src/dfs/source-policy.ts.txt) - [src/fees/policy.ts](https://docs.ammora.org/examples/source/src/fees/policy.ts.txt) - [src/shared/actions.ts](https://docs.ammora.org/examples/source/src/shared/actions.ts.txt) - [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/dfs/sharing.example.json](https://docs.ammora.org/examples/source/src/dfs/sharing.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.