{"name":"SolKnife","version":"1.0.0","description":"Non-custodial Solana toolkit. Every UI action is reachable via JSON HTTP. Server builds unsigned transactions; the caller (user wallet or agent with key custody) signs; server self-submits.","site":"https://solknife.xyz","humanDocs":"https://solknife.xyz/agents","pricingEndpoint":"/api/pricing","mcp":{"endpoint":"https://solknife.xyz/api/mcp","transport":"streamable-http","phase":"1-2-3-reads-builds-submits","x402Gated":true,"freeMethods":["completion/complete","initialize","notifications/cancelled","notifications/initialized","ping","prompts/list","resources/list","resources/templates/list","tools/list"]},"openapi":"https://solknife.xyz/openapi.json","x402":{"enabled":true,"version":2,"network":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","exact":{"scheme":"exact","amount":"10000","asset":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","payTo":"6bh83R94PBoYgzQXzXwoyh93s4ibQvnfgjmggNxkxNYb","feePayer":"H6Nr4y4ahDUjkDexD7c78thW9fgZJLLQHBA7S6Xx1676","maxTimeoutSeconds":60},"legacy":{"scheme":"solknife-sol-landed","lamports":"150000","recipient":"6bh83R94PBoYgzQXzXwoyh93s4ibQvnfgjmggNxkxNYb","retryHeader":"X-Payment"},"bypassOrigin":"https://solknife.xyz","legacyOriginBypass":false,"sessionCookie":"solknife-session","sessionAuth":{"challengeEndpoint":"/api/auth/challenge","verifyEndpoint":"/api/auth/verify","logoutEndpoint":"/api/auth/logout","scheme":"siws","ttlSeconds":3600},"gatedPaths":["/api/check","/api/portfolio","/api/portfolio/compose/plan","/api/portfolio/compose/build","/api/positions","/api/pool","/api/pool-compare","/api/token-meta","/api/reclaim-rent/accounts","/api/revoke-authority/mint","/api/token-metadata/state","/api/mint-supply/mint","/api/burn-nft/assets","/api/confidential-transfer/state","/api/confidential-transfer/orphans/list","/api/create-mint/build","/api/mint-supply/build","/api/create-account/build","/api/reclaim-rent/build","/api/revoke-authority/build","/api/token-metadata/build","/api/burn-nft/build","/api/swap/order","/api/confidential-transfer/build","/api/confidential-transfer/deposit/build","/api/confidential-transfer/apply-pending/build","/api/confidential-transfer/empty-and-close/build","/api/confidential-transfer/withdraw/build","/api/confidential-transfer/transfer/build","/api/confidential-transfer/orphans/build","/api/arweave/upload","/api/mcp"],"retryHeader":"PAYMENT-SIGNATURE","settlementHeader":"PAYMENT-RESPONSE","verification":"`exact`: send a base64 PaymentPayload in PAYMENT-SIGNATURE carrying a partially signed, UNSUBMITTED tx naming `exact.feePayer` as fee payer. Instruction layout must be SetComputeUnitLimit, SetComputeUnitPrice (≤ 5 lamports/CU), TransferChecked of ≥ `exact.amount` USDC to the derived ATA of (payTo, asset) — not the bare wallet — then optional Memo/Lighthouse; 3-6 ixs, no address lookup tables. When `nonceRequired`, the Memo must carry the challenge's `extra.memo` nonce (HMAC-verified, TTL-bounded, claimed exactly once). We simulate, co-sign as feePayer, submit, and return PAYMENT-RESPONSE. `legacy`: pay lamports yourself, then retry with X-Payment: <base58 landed signature>; verified via getTransaction and deduped per signature.","phase":2,"nonceRequired":true,"nonceTtlSeconds":600,"memoPrograms":["Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo","MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr"]},"categories":[{"label":"Token safety + discovery","tools":[{"id":"check.scan","summary":"Check a Solana token for rug risk","kind":"read","method":"GET","path":"/api/check","purpose":"Rug-check a Solana token: freeze authority, sellability, holders, liquidity.","inputs":["mint"]},{"id":"token.meta","summary":"Fetch token metadata for a mint","kind":"read","method":"GET","path":"/api/token-meta","purpose":"Fetch token metadata (name, symbol, decimals, image) for a mint.","inputs":["mint"]},{"id":"portfolio.holdings","kind":"read","method":"GET","path":"/api/portfolio","purpose":"List a wallet's priced token holdings.","inputs":["owner"]},{"id":"portfolio.compose.plan","summary":"Generate a USD-valued portfolio rebalance plan","kind":"read","method":"POST","path":"/api/portfolio/compose/plan","purpose":"Plan a USD-valued portfolio rebalance from target mint percentages.","inputs":["owner","targets","slippageBps"]},{"id":"portfolio.compose.build","summary":"Generate an unsigned auto-compose transaction","kind":"build","method":"POST","path":"/api/portfolio/compose/build","purpose":"Build a best-effort single auto-compose transaction for a target portfolio.","inputs":["owner","targets","slippageBps"]},{"id":"portfolio.compose.execute","kind":"submit","method":"POST","path":"/api/portfolio/compose/execute","purpose":"Submit a wallet-signed portfolio compose transaction.","inputs":["owner","signedTransaction","lastValidBlockHeight"]}]},{"label":"DLMM (Meteora) liquidity","tools":[{"id":"pool.check","summary":"Read one DLMM pool's depth, volume, fees, and safety","kind":"read","method":"GET","path":"/api/pool","purpose":"Read one DLMM pool: depth, volume, fee yield, token safety summary.","inputs":["address"]},{"id":"positions.list","kind":"read","method":"GET","path":"/api/positions","purpose":"List a wallet's open Meteora DLMM positions with PnL.","inputs":["owner"]},{"id":"pool.compare","kind":"read","method":"GET","path":"/api/pool-compare","purpose":"Compare every DLMM pool for a token side by side.","inputs":["mint"]}]},{"label":"Swap","tools":[{"id":"swap.order","summary":"Fetch a Jupiter quote and unsigned swap transaction","kind":"build","method":"POST","path":"/api/swap/order","purpose":"Jupiter quote + unsigned swap transaction.","inputs":["inputMint","outputMint","amount","slippageBps","userPubkey"]},{"id":"swap.execute","kind":"submit","method":"POST","path":"/api/swap/execute","purpose":"Submit a wallet-signed swap transaction.","inputs":["signedTransaction","lastValidBlockHeight"]}]},{"label":"Token lifecycle (SPL + Token-2022)","tools":[{"id":"create-mint.build","summary":"Generate an unsigned create-mint transaction","kind":"build","method":"POST","path":"/api/create-mint/build","purpose":"Build an unsigned create-mint tx (extensions incl. confidential transfer).","inputs":["owner","decimals","extensions"]},{"id":"create-mint.execute","kind":"submit","method":"POST","path":"/api/create-mint/execute","purpose":"Submit the signed create-mint tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"mint-supply.read","kind":"read","method":"GET","path":"/api/mint-supply/mint","purpose":"Read a mint's authority state for mint-to.","inputs":["mint"]},{"id":"mint-supply.build","summary":"Generate an unsigned mint-to transaction","kind":"build","method":"POST","path":"/api/mint-supply/build","purpose":"Build an unsigned mint-to tx.","inputs":["mint","destination","amount"]},{"id":"mint-supply.execute","kind":"submit","method":"POST","path":"/api/mint-supply/execute","purpose":"Submit the signed mint-to tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"token-metadata.read","kind":"read","method":"GET","path":"/api/token-metadata/state","purpose":"Read a mint's current on-chain Metaplex metadata.","inputs":["mint"]},{"id":"token-metadata.build","summary":"Generate an unsigned set or update metadata transaction","kind":"build","method":"POST","path":"/api/token-metadata/build","purpose":"Build an unsigned set/update metadata tx.","inputs":["mint","owner","name","symbol","uri"]},{"id":"token-metadata.execute","kind":"submit","method":"POST","path":"/api/token-metadata/execute","purpose":"Submit the signed metadata tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"revoke-authority.read","summary":"Read a mint's authorities before revoking them","kind":"read","method":"GET","path":"/api/revoke-authority/mint","purpose":"Read a mint's current mint + freeze authorities.","inputs":["mint"]},{"id":"revoke-authority.build","summary":"Generate an unsigned revoke-authority transaction","kind":"build","method":"POST","path":"/api/revoke-authority/build","purpose":"Build an unsigned revoke-authority tx.","inputs":["mint","owner","authorities"]},{"id":"revoke-authority.execute","kind":"submit","method":"POST","path":"/api/revoke-authority/execute","purpose":"Submit the signed revoke-authority tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"change-authority.read","summary":"Read a mint's authorities before transferring them","kind":"read","method":"GET","path":"/api/change-authority/mint","purpose":"Read a mint's current mint + freeze authorities.","inputs":["mint","owner"]},{"id":"change-authority.build","summary":"Generate an unsigned change-authority transaction","kind":"build","method":"POST","path":"/api/change-authority/build","purpose":"Build an unsigned change-authority tx (transfer mint and/or freeze authority to a new address).","inputs":["payer","mint","newAuthority","changeMint","changeFreeze"]},{"id":"change-authority.execute","kind":"submit","method":"POST","path":"/api/change-authority/execute","purpose":"Submit the signed change-authority tx.","inputs":["signedTransaction","lastValidBlockHeight"]}]},{"label":"Token accounts","tools":[{"id":"create-account.build","summary":"Generate an unsigned ATA-create transaction","kind":"build","method":"POST","path":"/api/create-account/build","purpose":"Build an unsigned ATA-create tx (SPL or Token-2022).","inputs":["owner","mint","tokenProgram"]},{"id":"create-account.execute","kind":"submit","method":"POST","path":"/api/create-account/execute","purpose":"Submit the signed ATA-create tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"reclaim-rent.list","kind":"read","method":"GET","path":"/api/reclaim-rent/accounts","purpose":"List a wallet's reclaimable empty token accounts.","inputs":["owner"]},{"id":"reclaim-rent.build","summary":"Generate unsigned transactions to close empty accounts","kind":"build","method":"POST","path":"/api/reclaim-rent/build","purpose":"Build chunked close-batch tx(s).","inputs":["owner","accounts"]},{"id":"reclaim-rent.execute","kind":"submit","method":"POST","path":"/api/reclaim-rent/execute","purpose":"Submit the signed close-batch tx(s).","inputs":["owner","signedTransactions","lastValidBlockHeight"]},{"id":"burn-nft.list","kind":"read","method":"GET","path":"/api/burn-nft/assets","purpose":"List a wallet's NFT assets (DAS).","inputs":["owner"]},{"id":"burn-nft.build","summary":"Generate unsigned burn transactions for selected NFTs","kind":"build","method":"POST","path":"/api/burn-nft/build","purpose":"Build chunked burn tx(s) for selected NFTs.","inputs":["owner","assets"]},{"id":"burn-nft.execute","kind":"submit","method":"POST","path":"/api/burn-nft/execute","purpose":"Submit the signed burn tx(s).","inputs":["owner","signedTransactions","lastValidBlockHeight"]}]},{"label":"Confidential transfer (Token-2022)","tools":[{"id":"ct.state","summary":"Read confidential-transfer state for an owner and mint","kind":"read","method":"GET","path":"/api/confidential-transfer/state","purpose":"Read CT state for owner + mint (mint extension, account configured, balance ciphertexts).","inputs":["owner","mint"]},{"id":"ct.orphans.list","kind":"read","method":"GET","path":"/api/confidential-transfer/orphans/list","purpose":"List a wallet's orphan ZK Proof context-state accounts.","inputs":["owner"]},{"id":"ct.configure.build","summary":"Generate an unsigned Configure transaction","kind":"build","method":"POST","path":"/api/confidential-transfer/build","purpose":"Build the Configure tx. Needs worker-generated PubkeyValidity proof + zero AES ciphertext.","inputs":["owner","mint","pubkeyValidityProof","decryptableZeroBalance"]},{"id":"ct.deposit.build","summary":"Generate an unsigned Deposit transaction","kind":"build","method":"POST","path":"/api/confidential-transfer/deposit/build","purpose":"Build the Deposit tx: move a public balance to confidential pending.","inputs":["owner","mint","amount","decimals"]},{"id":"ct.apply-pending.build","summary":"Generate an unsigned ApplyPending transaction","kind":"build","method":"POST","path":"/api/confidential-transfer/apply-pending/build","purpose":"Build the ApplyPending tx. Needs worker-computed new AES decryptable + counter.","inputs":["owner","mint","expectedPendingCounter","newDecryptableAvailable"]},{"id":"ct.empty-and-close.build","summary":"Generate an unsigned Empty and Close transaction","kind":"build","method":"POST","path":"/api/confidential-transfer/empty-and-close/build","purpose":"Build the Empty+Close tx. Needs worker-generated zero-ciphertext proof.","inputs":["owner","mint","zeroCiphertextProof"]},{"id":"ct.withdraw.build","summary":"Generate the unsigned Withdraw transaction saga","kind":"build","method":"POST","path":"/api/confidential-transfer/withdraw/build","purpose":"Build the 5-tx Withdraw saga. Needs equality + range U64 proofs + new AES decryptable.","inputs":["owner","mint","amount","decimals","equalityContextAccount","rangeContextAccount","equalityProof","rangeProof","newDecryptableAvailable"]},{"id":"ct.transfer.build","summary":"Generate the unsigned Transfer transaction saga","kind":"build","method":"POST","path":"/api/confidential-transfer/transfer/build","purpose":"Build the 5-tx Transfer saga. Needs equality + 3HV + range U128 proofs + auditor ciphertexts.","inputs":["owner","mint","destinationTokenAccount","equalityContextAccount","validityContextAccount","rangeContextAccount","equalityProof","validityProof","rangeProof","newSourceDecryptableAvailable","auditorCiphertextLo","auditorCiphertextHi"]},{"id":"ct.orphans.build","summary":"Generate unsigned transactions to reclaim orphan ZK rent","kind":"build","method":"POST","path":"/api/confidential-transfer/orphans/build","purpose":"Build chunked CloseContextState tx(s) to reclaim orphan ZK ctx rent.","inputs":["owner","addresses"]},{"id":"ct.submit","summary":"Submit a signed confidential-transfer transaction or saga","kind":"submit","method":"POST","path":"/api/confidential-transfer/submit","purpose":"Submit any signed CT tx or saga. Op discriminator routes to verifier + sequential submitter.","inputs":["op","signedTransaction OR signedTransactions","lastValidBlockHeight"]}]},{"label":"Multisig (Squads v4)","tools":[{"id":"multisig.create.build","summary":"Generate an unsigned create-multisig transaction","kind":"build","method":"POST","path":"/api/multisig/create/build","purpose":"Build an unsigned create-multisig tx (members, threshold). Returns the multisig + vault address.","inputs":["creator","createKey","members","threshold"]},{"id":"multisig.create.execute","kind":"submit","method":"POST","path":"/api/multisig/create/execute","purpose":"Submit the signed create-multisig tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"multisig.propose.build","summary":"Generate an unsigned propose-transaction transaction","kind":"build","method":"POST","path":"/api/multisig/propose/build","purpose":"Build an unsigned propose-transaction tx: a SOL transfer, a token transfer, or arbitrary instructions, run through the vault.","inputs":["multisig","proposer","kind"]},{"id":"multisig.propose.execute","kind":"submit","method":"POST","path":"/api/multisig/propose/execute","purpose":"Submit the signed propose-transaction tx.","inputs":["signedTransaction","lastValidBlockHeight"]},{"id":"multisig.state","summary":"Read a Squads multisig's members, vault, and proposals","kind":"read","method":"GET","path":"/api/multisig/state","purpose":"Read a Squads multisig: members, threshold, vault balance, and pending proposals with vote tallies.","inputs":["address"]},{"id":"multisig.approve.build","summary":"Generate an unsigned approve or reject vote transaction","kind":"build","method":"POST","path":"/api/multisig/approve/build","purpose":"Build an unsigned vote tx: approve or reject a proposal.","inputs":["multisig","member","transactionIndex","vote"]},{"id":"multisig.approve.execute","kind":"submit","method":"POST","path":"/api/multisig/approve/execute","purpose":"Submit the signed vote tx (pass the same vote value back).","inputs":["signedTransaction","lastValidBlockHeight","vote"]},{"id":"multisig.execute.build","summary":"Generate an unsigned execute-proposal transaction","kind":"build","method":"POST","path":"/api/multisig/execute/build","purpose":"Build an unsigned execute tx for an approved proposal (vault or config, auto-detected).","inputs":["multisig","member","transactionIndex"]},{"id":"multisig.execute.execute","summary":"Submit the signed execute-proposal transaction","kind":"submit","method":"POST","path":"/api/multisig/execute/execute","purpose":"Submit the signed execute-proposal tx (pass the executeKind back).","inputs":["signedTransaction","lastValidBlockHeight","executeKind"]},{"id":"multisig.config.build","summary":"Generate an unsigned config-change proposal","kind":"build","method":"POST","path":"/api/multisig/config/build","purpose":"Build an unsigned config-change proposal: add a member, remove a member, or change the threshold.","inputs":["multisig","proposer","op"]},{"id":"multisig.config.execute","kind":"submit","method":"POST","path":"/api/multisig/config/execute","purpose":"Submit the signed config-change proposal tx.","inputs":["signedTransaction","lastValidBlockHeight"]}]},{"label":"Storage","tools":[{"id":"arweave-upload.relay","summary":"Upload a base64 file to Arweave via a funded Irys account","kind":"submit","method":"POST","path":"/api/arweave/upload","purpose":"Agent relay: upload a base64-encoded file to Arweave via SolKnife's funded Irys account. x402-gated.","inputs":["fileBase64","contentType"]}]}],"notes":{"walletSigning":"Every `build` returns an unsigned base64 v0 transaction. The caller signs (user wallet adapter, or a programmatic Solana Keypair for an agent with key custody) then posts the signed bytes to the matching `submit` or `execute` endpoint. The server never holds a key with authority over your funds. The one key it does hold is the x402 `exact.feePayer`, which the protocol requires it to co-sign payment transactions with as fee payer; it sponsors network fees and can move nothing of yours.","workerBound":"Confidential-transfer build endpoints require ZK proof bytes that are generated from the user's ElGamal + AES keys. Those keys are derived from a wallet signature and live only in a Web Worker (lib/zk/proof.worker.ts). An agent that wants to drive CT autonomously has to embed the worker logic in its own runtime, becoming the key-holder. The full proof spec, key derivation, byte lengths, op-by-op input map, and a Node reference implementation are documented at /agents/confidential-transfer. Non-CT flows are fully HTTP-callable without any worker.","fees":"Fees are env-driven per op. Swap fee accrues to a wSOL token account (SOLKNIFE_FEE_ACCOUNT / SOLKNIFE_FEE_BPS). Plain-SOL fees (reclaim-rent, create-mint, mint-supply, token-metadata, revoke-authority, burn-nft, CT deposit/apply/withdraw/transfer/reclaim) accrue to SOLKNIFE_FEE_WALLET via flat lamport transfers wired into the build output. All default to 0 (disabled) until the operator opts in.","x402":"Live state in the top-level `x402` field. When `x402.enabled` is true, gated paths (`x402.gatedPaths`) answer HTTP 402 with an x402 v2 PaymentRequired body — `{ x402Version: 2, resource, accepts: [...] }` — mirrored base64 in the PAYMENT-REQUIRED header. Prefer `accepts[0]`, the `exact` scheme: pay `x402.exact.amount` USDC (ATOMIC units) to the derived associated token account of (`payTo`, `asset`), NOT to the bare wallet, in a transaction that names `x402.exact.feePayer` as fee payer and that you sign but do NOT submit. Instruction layout: SetComputeUnitLimit, SetComputeUnitPrice, TransferChecked, then optional Memo/Lighthouse. When `x402.nonceRequired`, the Memo must carry the challenge's `extra.memo` nonce, which expires after `x402.nonceTtlSeconds`. Send it base64-JSON in the PAYMENT-SIGNATURE header; we verify, co-sign as fee payer, submit, and return the receipt in PAYMENT-RESPONSE. The `x402.legacy` entry is a deprecated pay-then-prove path (send lamports yourself, retry with X-Payment: <base58 landed signature>) kept only for existing callers; no standard x402 client can pay it. Two ways to bypass payment: (1) sign in with a Solana wallet via SIWS at `x402.sessionAuth.challengeEndpoint` + `verifyEndpoint`, which sets the HttpOnly `x402.sessionCookie` for `x402.sessionAuth.ttlSeconds`; it is HMAC-signed and binds to a verified pubkey. (2) Legacy Origin bypass, only when `x402.legacyOriginBypass` is true; Origin is trivially spoofable so it is off by default. MCP is charged per operation, not per endpoint: `mcp.freeMethods` (initialize, tools/list, ...) are never charged, so an agent can connect and browse before buying. When `x402.enabled` is false the gate is a no-op."}}