{"_id":"@apecover/sdk","_rev":"3-d024979c02449663b3a19c06e288c90e","name":"@apecover/sdk","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@apecover/sdk","version":"0.1.0","keywords":["solana","defi","insurance","memecoin","pumpfun","trading-bot","rug-pull","apecover"],"license":"MIT","_id":"@apecover/sdk@0.1.0","maintainers":[{"name":"rider-0825","email":"khishchenkomykola@gmail.com"}],"homepage":"https://volumex.insure","bugs":{"url":"https://github.com/Vetted-Pro/degen-trade-insurance/issues"},"dist":{"shasum":"69e092c6a9c39654d4bcf8273abeeb09bed35931","tarball":"https://registry.npmjs.org/@apecover/sdk/-/sdk-0.1.0.tgz","fileCount":22,"integrity":"sha512-FDdE3HE8ZnXb8Ln8t6l5KAuufaihk9/Pdof0eGAVbXdYVghpE5Oj/I0YtT0F6l5xFjYibXSVvZk0G3nvDPeFig==","signatures":[{"sig":"MEYCIQCU6AznMO71Qbcvu2rA31dl28iUmh58a1ILFd9IFma7iwIhAJEWxHWTqUcJ403YSzC6ScUui54t/3Nb7F5us1rkYXFR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":281034},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"5f090d4e1787c6d0b48ebc7b206cd174e64cd4fe","scripts":{"build":"tsc --build","clean":"rm -rf dist *.tsbuildinfo","prepack":"npm run clean && npm run build"},"_npmUser":{"name":"rider-0825","email":"khishchenkomykola@gmail.com"},"repository":{"url":"git+https://github.com/Vetted-Pro/degen-trade-insurance.git","type":"git","directory":"packages/apecover-sdk"},"_npmVersion":"11.6.2","description":"Rug cover for Solana memecoin trades. Insure a swap in one call, with an API key.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"bn.js":"^5.2.1","@apecover/core":"0.1.0","@solana/web3.js":"^1.98.4","@apecover/common":"0.1.0","@coral-xyz/anchor":"^0.32.1"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"bs58":"^6.0.0","@degen-insurance/api":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.1.0_1786922959033_0.46533419880015026","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@apecover/sdk","version":"0.2.0","keywords":["solana","defi","insurance","memecoin","pumpfun","trading-bot","rug-pull","apecover"],"license":"MIT","_id":"@apecover/sdk@0.2.0","maintainers":[{"name":"rider-0825","email":"khishchenkomykola@gmail.com"}],"homepage":"https://apecover.io","bugs":{"url":"https://github.com/Vetted-Pro/degen-trade-insurance/issues"},"dist":{"shasum":"e5251ca9c7a821d4fc973e6a3e0c1a75f0daeb45","tarball":"https://registry.npmjs.org/@apecover/sdk/-/sdk-0.2.0.tgz","fileCount":22,"integrity":"sha512-Jz2Q/PTo1SDSCx2cxo3F+jycsOfBc4lnNfXuxx5wJT08umHFC0C0y4sN4cy8dK/xt2O9TjCinXYpxskpvFHvEQ==","signatures":[{"sig":"MEQCIHQZeFnam6qM2cFI900uhLmMBOjN37HBmA7Q6s66vqAwAiB5n7tUIwLhbuMm8WtLeJuQzem/SecNkTj3/TN0gCbdrA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":283380},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"506e3f41f81aa4b9185f9ba24ca4b3229d4d2871","scripts":{"build":"tsc --build","clean":"rm -rf dist *.tsbuildinfo","prepack":"npm run clean && npm run build"},"_npmUser":{"name":"rider-0825","email":"khishchenkomykola@gmail.com"},"repository":{"url":"git+https://github.com/Vetted-Pro/degen-trade-insurance.git","type":"git","directory":"packages/apecover-sdk"},"_npmVersion":"11.6.2","description":"Rug cover for Solana memecoin trades. Insure a swap in one call, with an API key.","directories":{},"sideEffects":false,"_nodeVersion":"24.11.1","dependencies":{"bn.js":"^5.2.1","@apecover/core":"0.1.0","@solana/web3.js":"^1.98.4","@apecover/common":"0.1.0","@coral-xyz/anchor":"^0.32.1"},"publishConfig":{"access":"public","provenance":true},"_hasShrinkwrap":false,"devDependencies":{"bs58":"^6.0.0","@degen-insurance/api":"0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/sdk_0.2.0_1786928996797_0.06592411863765113","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@apecover/sdk","version":"0.4.0","description":"Rug cover for memecoin trades on Solana and Robinhood Chain. Insure a swap in one call, with an API key.","keywords":["solana","evm","robinhood","defi","insurance","memecoin","pumpfun","trading-bot","rug-pull","apecover"],"license":"MIT","homepage":"https://apecover.io","repository":{"type":"git","url":"git+https://github.com/Vetted-Pro/degen-trade-insurance.git","directory":"packages/apecover-sdk"},"bugs":{"url":"https://github.com/Vetted-Pro/degen-trade-insurance/issues"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"sideEffects":false,"engines":{"node":">=20"},"publishConfig":{"access":"public","provenance":true},"scripts":{"build":"tsc --build","clean":"rm -rf dist *.tsbuildinfo","prepack":"npm run clean && npm run build"},"dependencies":{"@apecover/common":"0.3.0","@apecover/core":"0.3.0","@coral-xyz/anchor":"^0.32.1","bn.js":"^5.2.1","@solana/web3.js":"^1.98.4"},"devDependencies":{"@degen-insurance/api":"0.1.0","bs58":"^6.0.0"},"gitHead":"35b422cba29d2dce62b69624c212b3fff979e168","_id":"@apecover/sdk@0.4.0","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-kJfCX9RPC2aqkguBe8R/V4hs56iTCk6aBrekQKKTrD2G+h2LZjbihCNLUOIEBfIou0gotUpUlNaNPmmkR79mDg==","shasum":"3e45b3e36b49b18a173e363117caef0ce09bea35","tarball":"https://registry.npmjs.org/@apecover/sdk/-/sdk-0.4.0.tgz","fileCount":37,"unpackedSize":445255,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDBjAwkqR9QEImttH4swtpVXdgluH5fz2/ItwKgQuMBsQIhAOf488vaKdtRbfsj+6otztyyxIo0DUUYONKaR5ndqBCw"}]},"_npmUser":{"name":"rider-0825","email":"khishchenkomykola@gmail.com"},"directories":{},"maintainers":[{"name":"rider-0825","email":"khishchenkomykola@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.4.0_1787748728290_0.8863824091012655"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-16T23:29:18.892Z","modified":"2026-08-26T12:52:08.711Z","0.1.0":"2026-08-16T23:29:19.176Z","0.2.0":"2026-08-17T01:09:57.019Z","0.4.0":"2026-08-26T12:52:08.503Z"},"bugs":{"url":"https://github.com/Vetted-Pro/degen-trade-insurance/issues"},"license":"MIT","homepage":"https://apecover.io","keywords":["solana","evm","robinhood","defi","insurance","memecoin","pumpfun","trading-bot","rug-pull","apecover"],"repository":{"type":"git","url":"git+https://github.com/Vetted-Pro/degen-trade-insurance.git","directory":"packages/apecover-sdk"},"description":"Rug cover for memecoin trades on Solana and Robinhood Chain. Insure a swap in one call, with an API key.","maintainers":[{"name":"rider-0825","email":"khishchenkomykola@gmail.com"}],"readme":"# @apecover/sdk\n\nRug cover for memecoin trades, in one call — on **Solana** and on **Robinhood Chain**.\n\nA trader enters a launch. If the token collapses more than 90% inside the coverage window, the\nprotocol pays out. This package is how a bot, a terminal or a backend buys that cover: one method,\nan API key, and the key that made the swap.\n\n```bash\nnpm install @apecover/sdk\n```\n\nThe quickstart below is Solana, which is where cover is live. The same call works on Robinhood\nChain — [Two chains](#two-chains) has what changes, and what is not deployed there yet.\n\n```ts\nimport { ApeCover } from '@apecover/sdk';\nimport { Connection, Keypair } from '@solana/web3.js';\n\nconst ape = new ApeCover({\n  apiKey: process.env.APECOVER_API_KEY!,\n  pool: process.env.APECOVER_POOL!, // which pool you insure against — see below\n  connection: new Connection(process.env.RPC_URL!, 'confirmed'),\n  signer: Keypair.fromSecretKey(secret),\n});\n\nconst result = await ape.insureTrade({\n  swapSignature, // the swap you just made\n  tokenMint, // what you bought\n  tradeSize: 300_000_000n, // lamports to insure — omit to insure the whole swap\n  tier: 'standard',\n});\n\nswitch (result.status) {\n  case 'insured':\n    console.log('covered', result.trade);\n    break;\n  case 'declined':\n    console.log('not covered:', result.reason, result.detail);\n    break;\n  case 'unknown':\n    console.log('sent, outcome pending', result.signature);\n    break;\n}\n```\n\nThat is the whole integration. Everything below is detail.\n\n---\n\n> **Changed in 0.2.0 — upgrade if you did not pass `baseUrl`.**\n>\n> The default endpoint moved from `https://volumex.insure/api` to `https://apecover.io/api`.\n> `volumex.insure` was the platform's original domain and has been retired; `apecover.io` is the\n> same deployment, the same pool and the same data.\n>\n> This only affects you if you constructed a client **without** `baseUrl` — that is the value\n> that changed. If you passed your own, nothing here concerns you.\n>\n> `0.1.0` keeps calling the old hostname, because a published version cannot be changed. It works\n> for as long as that domain keeps answering, which is not indefinitely. Upgrading is the fix;\n> pinning `baseUrl: 'https://apecover.io/api'` on `0.1.0` is the workaround if you cannot.\n\n---\n\n## Getting a key\n\nSign in at [apecover.io](https://apecover.io), open **Account**, and issue one. It is shown\nonce, looks like `dgn_….dgnsk_…`, and both halves are the key.\n\n**The key authenticates to ApeCover, never to Solana.** It cannot move lamports, cannot sign a\ntransaction and is not a wallet. Everything that spends money is signed locally by your keypair,\nwhich this package never transmits.\n\nWhat the key buys is the one thing you cannot do for yourself. Registering a trade requires the\npool's attestor to co-sign, because entry price and market cap are not computable on chain and a\nself-reported entry price is exactly the fraud the attestor exists to prevent. Without a key there\nis no co-signer; with one, `insureTrade` works.\n\nIf a key leaks, an attacker can request attestations and burn your rate limit. Each attestation is\na transaction built for one wallet, spending one policy that wallet holds, which that wallet must\nstill countersign — so nothing is spent and nothing is reserved. Revoke it anyway, from the same\npage.\n\n**The client refuses to construct in a browser.** A key in a page is readable by every visitor,\ncannot be scoped to one of them, and cannot be revoked for one without revoking it for everybody.\nThere is no flag to override this. Call it from your server.\n\n---\n\n## How cover works\n\nYou buy a **policy**: a prepaid pack of trade credits at one tier. Each insured trade spends one\ncredit. `insureTrade` buys a pack when you have none, so a first call may cost more than the ones\nafter it — see [buying up front](#buying-up-front) if you would rather that not land mid-trade.\n\n| Tier        | Premium          | Pays out | Window |\n| ----------- | ---------------- | -------- | ------ |\n| `basic`     | 3% of trade size | 25%      | 10 min |\n| `standard`  | 5%               | 50%      | 10 min |\n| `degen-max` | 10%              | 100%     | 15 min |\n\nCover attaches at entry and expires with the window. A collapse of more than 90% inside it is\nclaimable; the pool pays the tier's share of the insured size.\n\n---\n\n## The three outcomes\n\n`insureTrade` returns a result rather than throwing, because \"not covered\" is an ordinary answer.\n\n**`insured`** — the registration confirmed. Carries `trade`, `policy` and `signature`.\n\n**`declined`** — the protocol will not cover this trade, and `reason` is a stable code you can\nswitch on: `trade-too-small`, `trade-too-large`, `market-cap-too-high`,\n`insufficient-pool-capacity`, `pool-paused`, `no-credits`, `partner-exposure-cap`,\n`partner-rate-limit`, `attestation-unavailable`. `detail` is a sentence for a human — log it, do\nnot parse it.\n\n**`unknown`** — the transaction was sent and has not confirmed in time. **This is not failure.**\nThe premium may be paid and the cover may exist; the fate is knowable, just not yet. Look up\n`result.signature`, or call `insureTrade` again — a second cover on the same swap is refused on\nchain, so retrying is safe.\n\nGenuine faults still throw: a malformed key, an unreachable cluster, no signer. Those mean you have\nsomething to fix, which is different news.\n\n---\n\n## Reading before you sign\n\nAn `insured` or `declined` result carries `facts` — everything the attestor put its name to:\n\n```ts\nif (result.facts) {\n  console.log(result.facts.entryPrice); // price, expo, conf, source, publishTs\n  console.log(result.facts.swapLamportsSpent); // what the swap actually spent, measured on chain\n  console.log(result.facts.liability); // what the pool reserves against this trade\n  console.log(result.facts.marketCapMicroUsd);\n}\n```\n\nSizes are `bigint`, always. Lamport figures pass 2^53 and a JSON number would round them silently.\n\n---\n\n<a id=\"two-chains\"></a>\n\n## Two chains\n\n`chain` is the whole of the difference at construction. Omit it and you get Solana — a\ncompatibility promise with a test on it, so every integration written before the option existed\nkeeps working untouched.\n\n|                    | Solana              | Robinhood Chain                               |\n| ------------------ | ------------------- | --------------------------------------------- |\n| `chain`            | omit, or `'solana'` | `'robinhood-testnet'` or `'robinhood'`        |\n| Signer             | a web3.js `Keypair` | anything with `address` and `sendTransaction` |\n| Reaching the chain | `connection`        | `evmAccess`                                   |\n| A trade or policy  | a base58 address    | a `uint256`, as a decimal string              |\n| ERC-20 approvals   | do not exist        | sent for you, once, and only when short       |\n| Settlement lag     | 0 s                 | up to 843 s — budget for it                   |\n\n```ts\nimport { ApeCover, type EvmChainAccess } from '@apecover/sdk';\n\nconst access: EvmChainAccess = {\n  allowance: (token, owner, spender) => erc20(token).allowance(owner, spender),\n  send: (call) => wallet.sendTransaction(call), // broadcast, return the hash\n  confirmed: (hash) => receiptStatus(hash), // true | false | null when not yet known\n  registration: (hash) => idsFromReceipt(hash), // { policyId, tradeId }\n};\n\nconst ape = new ApeCover({\n  apiKey: process.env.APECOVER_API_KEY!,\n  pool: process.env.APECOVER_POOL!, // the pool contract — 0x…\n  chain: 'robinhood-testnet',\n  signer: wallet, // { address, sendTransaction }\n  evmAccess: access,\n  settlement: { token: USDC, decimals: 6 }, // omit entirely for a native pool\n});\n\nconst result = await ape.insureTrade({ swapSignature, tokenMint, tier: 'standard' });\n```\n\nFour methods rather than a wallet library, because naming one would make it a dependency of\neverybody's build. `registration` is required rather than optional, and the reason is worth\nstating: an `insured` result carries a `trade` and a `policy`, on this chain those are `uint256`\nids, and a transaction hash is not a trade id. A client handed one there would look it up and find\nnothing — so the reader is part of the contract, refused at the call rather than papered over with\na plausible value.\n\n**A decline sends nothing.** The attestor is asked before any transaction goes out, so a trade the\nprotocol will not cover leaves no approval and no policy behind — you are not left holding a pack\nof credits you bought on the way to being refused.\n\n<a id=\"what-is-refused\"></a>\n\n### What is refused, and when\n\n**Wrong-family signer, wrong-family address and an unknown chain each throw from the constructor.**\nThat is the earliest point at which the mistake exists and the last at which nothing has happened\nyet. The signer is the one that earns the code: it is not exercised until something is sent, so an\ned25519 keypair on an EVM client survives `whoami`, `quote` and `pool` and fails at the single\nmoment money is moving.\n\n**Robinhood mainnet (4663) is not enabled**, and `insureTrade` checks that before it builds\nanything. Nothing is deployed on 4663. `robinhood-testnet` is enabled, and the pool proxy\n`0x932e54A4929f156154dABa61d30abe5172542370` is deployed and verified on 46630 — whether that pool\nwill underwrite your trade is a live question about the pool rather than the chain, and\n`ape.pool()` is the answer. Ask about the chain at start-up rather than at your first trade:\n\n```ts\nimport { requireChainEnabled } from '@apecover/sdk';\n\nrequireChainEnabled('robinhood'); // throws, with the reason attached\n```\n\n### Ask what a chain can do — do not catch it\n\n```ts\nif (ape.capabilities.approvals) {\n  // ERC-20 allowances exist here. On Solana this branch never runs.\n}\nape.capabilities.settlementLagSeconds; // 0 on Solana, 843 on 4663\nape.chainName; // which chain this client was built for\n```\n\nEvery field is a property of the **chain**, never of your pool, so reading one costs no round trip.\nA bot that learned the same differences by handling exceptions would have to tell \"this chain\ncannot\" apart from \"this call failed\", and those two arrive identically.\n\n`settlementLagSeconds` is the one to actually budget against. It is `0` on Solana, where reverting\na `confirmed` write needs a supermajority fork. On 4663 it is `843` — the measured **peak** of how\nfar the `safe` tag stepped behind head, not an average, because the tag steps rather than lags.\nThat is longer than a `basic` or `standard` trade's entire coverage window.\n\n### Still Solana-only\n\n`buyPolicy()`, `protocol()` and `chain()` reach the Anchor program directly, so they need a\n`Connection` and a Solana keypair and throw on an EVM client. `insureTrade`, `quote`, `pool`,\n`whoami` and `capabilities` work on both.\n\n---\n\n## API\n\n### `new ApeCover(options)`\n\n| Option            | Required                | Meaning                                                          |\n| ----------------- | ----------------------- | ---------------------------------------------------------------- |\n| `apiKey`          | yes                     | `dgn_….dgnsk_…`                                                  |\n| `pool`            | yes                     | The pool you insure against. See [Which pool](#which-pool)       |\n| `chain`           | no                      | `'solana'` (the default), `'robinhood-testnet'` or `'robinhood'` |\n| `signer`          | for anything on chain   | The key that made the swap and will own the cover                |\n| `connection`      | on Solana, for on chain | A web3.js `Connection` on the pool's cluster                     |\n| `evmAccess`       | on an EVM chain         | How this client reads an allowance and sends a call              |\n| `settlement`      | on an EVM ERC-20 pool   | `{ token, decimals }`. Absent means a native pool                |\n| `programId`       | no                      | Read from the pool when omitted, once per client                 |\n| `partner`         | no                      | The partner account premiums are attributed to                   |\n| `defaultPackSize` | no                      | Credits bought when a policy has to be created. Default 10       |\n| `baseUrl`         | no                      | For a private deployment or a local API                          |\n\nA missing or malformed `pool` throws from the constructor, naming the option. So does a `chain`\nthat is not one, a signer from the wrong family, and a pool address that belongs to the other\nchain — see [what is refused](#what-is-refused).\n\nAn EVM client takes no `connection`: its signer carries its own transport, because a wallet that\ncan sign is already connected to a node, and asking for a second endpoint invites the two to\ndisagree about the head.\n\n<a id=\"which-pool\"></a>\n\n#### Which pool\n\nA deployment may index more than one, and only you know which one your integration is for, so\nthere is no default and nothing to discover — the platform serves `GET /pool/{address}` and\nnothing that answers _which_ address. There is no endpoint that lists them; take the address from\nthe dashboard or from whoever runs the deployment.\n\nThe current devnet pool is `3J31LrGG5Ko7iECH4o4QCdh7vXfShUHc2Npww2pCQPaH`. Confirm any address\nbefore you trade against it — `GET /pool/{address}` returning 200 is the check, and\n`ape.pool()` does it for you.\n\n> **Changed in 0.1.0.** `pool` was previously optional and documented as defaulting to \"the\n> platform's advertised deployment\". No such endpoint exists, so that default resolved to\n> `GET /pool` — a route the API does not serve — and every client that relied on it 404'd at its\n> first on-chain call. If you have code in the old shape it will now throw at construction rather\n> than fail one round trip later. It was never working; this only moves where you find out.\n\n### `insureTrade(params)`\n\nReuses a policy with credits or buys one, obtains the attestation, countersigns and sends.\n\n### `buyPolicy(tier, coveredTradeSize)`\n\n<a id=\"buying-up-front\"></a>\n\nBuys a pack now. Worth doing at start-up: buying is an on-chain purchase with its own confirmation\nwait, and leaving it to the first trade adds that wait to whichever trade is unlucky enough to be\nfirst.\n\n```ts\nawait ape.buyPolicy('standard', 1_000_000_000n);\n```\n\n### `quote(params)`\n\nWhat a trade would cost and whether the pool can take it. No signer needed.\n\n```ts\nconst q = await ape.quote({\n  tier: 'standard',\n  tradeSize: 300_000_000n,\n  tokenMint, // required: the entry gate is priced against this token\n  packSize: 10, // optional, default 1\n});\n```\n\n`tokenMint` is not optional. Eligibility turns on the token's market cap at entry, so a quote\nwithout one is not a quote — the endpoint refuses it rather than guessing.\n\n> **Changed in 0.1.0.** This took positional `(tier, tradeSize)` and sent\n> `GET /quote?tier=standard&…`. The API serves `POST /quote` and always has, with a body requiring\n> `tokenMint`, `packSize` and a _numeric_ tier, so no arguments to the old signature could produce\n> an accepted request.\n\n### `pool()` / `whoami()`\n\nThe pool's live state; the partner a key belongs to. `whoami` is the cheapest way to check a key\nworks — do it at start-up rather than discovering a bad key on your first real trade.\n\n### `chain()`\n\nThe underlying `InsuranceClient` for anything this class does not wrap.\n\n---\n\n## The rest of the protocol\n\nBuying cover is not the only thing there is to do. Claims, underwriting, the expiry crank and\npartner fees are all here, on `ape.protocol()`.\n\n**None of them uses your API key.** They are plain program instructions signed by your keypair, and\nthe platform is not in the path. A claim submitted through this SDK goes to the chain, not to us —\nif ApeCover disappeared tomorrow, everything in this section still works and only `insureTrade`\nstops.\n\n```ts\nconst protocol = await ape.protocol();\n```\n\n### Claiming\n\nThe digest comes from the platform: once the watcher rules a rug and seals the evidence, the\ntrade's proof is served at `GET /trades/:address/proof` — digest (hex and bytes), the IPFS CID of\nthe full bundle, and `retainUntil`, the last unix second a claim will still be accepted.\n\n```ts\nconst proof = await fetch(`${API_URL}/trades/${trade}/proof`).then((r) => {\n  if (r.status === 404) throw new Error('no proof held — not ruled a rug (yet)');\n  if (!r.ok) throw new Error(`platform cannot answer right now (${r.status}) — retry`);\n  return r.json();\n});\n\nawait protocol.submitClaim({\n  trade, // the InsuredTrade that rugged\n  proofDigest: Uint8Array.from(proof.digestBytes), // 32-byte multihash of the pinned bundle\n  proofCodec: 0x12, // sha2-256\n  bond: 10_000_000n, // escrowed; forfeited if the claim is rejected\n});\n```\n\nOnly the digest goes on chain. The verifier checks the evidence behind it and either finalises or\nrejects; the bond is what makes filing cost something. A 502/503 from the proof route means the\nplatform cannot answer, not that there is no rug — retry it; only a 404 is a statement about the\ntrade.\n\n### Underwriting\n\nTaking the other side: premiums accrue to you, payouts come out of you.\n\n```ts\nawait protocol.underwrite(5_000_000_000n); // stake 5 SOL\nawait protocol.claimRewards(); // collect the premium share earned\nawait protocol.withdrawStake(1_000_000_000n); // subject to lockup and live liabilities\n```\n\nOne position per wallet per pool — staking again adds to it. Amounts are base units of the\npool's settlement asset — the `5 SOL` above is only right because that pool settles natively; on\na USDC pool the same call stakes 5,000 USDC.\n\nYou do not need a wallet connected to anything to watch the position: the pool's realised APY\n(and the spread between yield venues report and yield that arrives) is on the site's `/stats`\npage, and any address's stake — value, P&L after socialised losses, claimable yield, lockup —\nis on `/positions`. Both are public reads; the withdraw above is the only part that needs your\nkey.\n\n### The expiry crank\n\n```ts\nawait protocol.expireTrade({ trade, policy, owner });\n```\n\nPermissionless, and worth doing. Nothing releases reserved liability when a coverage window closes\nwithout a claim, so `total_liabilities` would only ever grow and the pool would stop being able to\nsell cover. If you insure trades, crank your own expired ones — it costs one signature.\n\n### Partner fees\n\n```ts\nawait protocol.claimPartnerFees({ partner, feeDestination, amount });\n```\n\n`amount` is explicit rather than \"everything\", so draw-downs reconcile. Ask for more than is owed\nand the program refuses rather than clamping.\n\n### Results\n\nEvery call here returns `confirmed`, `failed` or `unknown` — the same three-way answer as\n`insureTrade`, for the same reason. `unknown` means sent and not yet confirmed; look the signature\nup rather than treating it as failure.\n\n---\n\n## Errors\n\n`ApeCoverError` carries `status` and, when the server sent one, `retryAfterSeconds`. Rate limits\nand 5xx responses are retried automatically, honouring `Retry-After`; 4xx responses are not,\nbecause the same key and the same body ask the same question.\n\n---\n\n## Running your own attestor\n\nIf you operate a pool you do not need a key. Import `InsuranceClient` directly and supply your own\n`AttestationSource` — the API key exists to fill that seam for everyone who is not you.\n\n```ts\nimport { InsuranceClient } from '@apecover/sdk';\n```\n\n---\n\n## Requirements\n\nNode 20+. `@solana/web3.js` and `@coral-xyz/anchor` come along as dependencies — including on an\nEVM integration, which imports none of them at runtime but still installs them.\n\nMIT licensed. Issues and source:\n[github.com/Vetted-Pro/degen-trade-insurance](https://github.com/Vetted-Pro/degen-trade-insurance).\n\n**This is a devnet deployment.** The cover it sells is not a regulated insurance product.\n","readmeFilename":"README.md"}