diff --git a/.dev/docs_check.ts b/.dev/docs_check.ts new file mode 100644 index 00000000..29247f96 --- /dev/null +++ b/.dev/docs_check.ts @@ -0,0 +1,59 @@ +/** + * Verifies that the repository-native documentation stays complete and GitHub-renderable. + * + * @module + */ + +import { readdir } from "node:fs/promises"; +import { dirname, join, relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; + +const ROOT_DIR: string = resolve(dirname(fileURLToPath(import.meta.url)), ".."); +const DOCS_DIR: string = join(ROOT_DIR, "docs"); +const SUMMARY_PATH: string = join(DOCS_DIR, "SUMMARY.md"); + +async function markdownFiles(dir: string): Promise { + const files: string[] = []; + for (const entry of await readdir(dir, { withFileTypes: true })) { + const path = join(dir, entry.name); + if (entry.isDirectory()) { + files.push(...(await markdownFiles(path))); + } else if (entry.name.endsWith(".md")) { + files.push(path); + } + } + return files; +} + +function fail(messages: readonly string[]): never { + throw new Error(`Documentation check failed:\n${messages.map((message) => `- ${message}`).join("\n")}`); +} + +const files: string[] = (await markdownFiles(DOCS_DIR)).sort(); +const relativeFiles: string[] = files.map((path) => relative(DOCS_DIR, path)); +const pages: string[] = relativeFiles.filter((path) => path !== "SUMMARY.md"); +const summary: string = await Bun.file(SUMMARY_PATH).text(); +const summaryLinks: string[] = [...summary.matchAll(/\]\(([^)#?]+\.md)(?:#[^)]+)?\)/g)].map((match) => match[1]!); + +const errors: string[] = []; +const duplicateLinks: string[] = summaryLinks.filter((link, index) => summaryLinks.indexOf(link) !== index); +if (duplicateLinks.length > 0) { + errors.push(`SUMMARY.md contains duplicate pages: ${[...new Set(duplicateLinks)].join(", ")}`); +} + +for (const page of pages) { + if (!summaryLinks.includes(page)) errors.push(`SUMMARY.md is missing ${page}`); +} +for (const link of summaryLinks) { + if (!pages.includes(link)) errors.push(`SUMMARY.md links to a missing or non-page file: ${link}`); +} + +for (const path of files) { + const source: string = await Bun.file(path).text(); + if (source.includes("{%")) { + errors.push(`${relative(DOCS_DIR, path)} contains unsupported GitBook directives`); + } +} + +if (errors.length > 0) fail(errors); +console.log(`Documentation index covers all ${pages.length} pages; no GitBook directives found.`); diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..77606d65 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,2 @@ +# @joeblau is the maintainer for this repository. +* @joeblau diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 797e591d..5b231dd1 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -30,14 +30,14 @@ Every task in this repo runs through Bun. There is no other toolchain. | Command | What it does | | ------------------------------ | -------------------------------------------------------------------- | | `bun install` | Install dependencies. | -| `bun run check` | Format, lint, TypeScript 5 + 7 types, JSDoc sync, export sync. | +| `bun run check` | Format, lint, docs, TypeScript 5 + 7, JSDoc sync, export sync. | | `bun test tests/` | Full test suite; the online tests need network and credentials. | | `HL_OFFLINE=1 bun test tests/` | Offline gate: skips every live-endpoint test. This is what CI runs. | | `bun run perf` | Performance suite; prints a table (`--out ` writes JSON). | | `bun run perf:gate` | Zero-performance-regression gate (see below). | | `bun run build` | Emit the publishable package into `dist/`. | -`bun run check` is a bundle of narrower scripts (`check:format`, `check:lint`, `check:types`, `check:ts7`, +`bun run check` is a bundle of narrower scripts (`check:format`, `check:lint`, `check:docs`, `check:types`, `check:ts7`, `check:jsdoc`, `check:export`) — run one directly when you only want to re-check that dimension. `bun run format` and `bun run lint` are the `--write` variants of the first two. @@ -86,7 +86,7 @@ that change. If the gate flaps on a busy machine, widen the band with `--thresho ## Coding Guidelines -- **Style**: After making all changes, run: `bun run check` (format, lint, TypeScript 5, TypeScript 7, doc/export sync). +- **Style**: After making changes, run `bun run check` (format, lint, docs, TypeScript 5 + 7, JSDoc/export sync). - **Performance**: Zero-regression policy — if you touch a hot path, run `bun run perf:gate` before opening a PR. - **Dependencies**: Use small and easily auditable dependencies (e.g. [@noble/hashes](https://www.npmjs.com/package/@noble/hashes) or [valibot](https://valibot.dev/)). diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index a4db4ee4..eda63f2f 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -25,8 +25,9 @@ jobs: # package.json calls `check` "everything CI gates on", and enumerating the steps here is how that # claim silently becomes false (it already had — the two sync gates below were missing entirely). # - # `check` runs, in order: biome format, biome lint, TypeScript 5 typecheck, the TypeScript 7 - # forward-compatibility gate (own install tree under .dev/ts7, since TS7 ships a native binary - # with no JS compiler API), the JSDoc sync check and the export sync check. + # `check` runs, in order: biome format, biome lint, repository-native documentation checks, + # TypeScript 5 typecheck, the TypeScript 7 forward-compatibility gate (own install tree under + # .dev/ts7, since TS7 ships a native binary with no JS compiler API), the JSDoc sync check and + # the export sync check. - name: Check run: bun run check diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..4bd7760b --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: Documentation + +on: + pull_request: + paths: + - "README.md" + - "docs/**" + - ".dev/docs_check.ts" + - ".github/CODEOWNERS" + - ".github/workflows/docs.yml" + - ".lycheeignore" + - ".markdownlint-cli2.jsonc" + - "package.json" + - "bun.lock" + workflow_dispatch: + +permissions: + contents: read + +jobs: + docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7 + - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2 + with: + # Match the rest of CI while Bun 1.4 remains canary-only. + bun-version: canary + + - name: Install dependencies + run: bun install --frozen-lockfile + + - name: Check documentation structure and formatting + run: bun run check:docs + + - name: Check documentation links + uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2 + with: + args: >- + --root-dir . + --no-progress + --max-retries 3 + --timeout 20 + README.md + 'docs/**/*.md' + fail: true + failIfEmpty: true + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.lycheeignore b/.lycheeignore new file mode 100644 index 00000000..02eb035c --- /dev/null +++ b/.lycheeignore @@ -0,0 +1 @@ +^https://www\.npmjs\.com/package/@bloxwap/hyperliquid$ diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc new file mode 100644 index 00000000..1a83ef44 --- /dev/null +++ b/.markdownlint-cli2.jsonc @@ -0,0 +1,11 @@ +{ + "config": { + // This repository wraps prose at 120 columns, while the markdownlint default is 80. + "MD013": false, + // Separate GitHub alert blocks use blank quoted lines by design. + "MD028": false, + // The root README starts with centered HTML branding, and embedded HTML is intentional there. + "MD033": false, + "MD041": false + } +} diff --git a/README.md b/README.md index bb72ed72..70ac17b4 100644 --- a/README.md +++ b/README.md @@ -24,27 +24,31 @@ - **Integratable**: Easy to use with [viem](https://github.com/wevm/viem) accounts — local (private key) or JSON-RPC (browser wallet). +## Documentation + +Browse the [SDK documentation](docs/README.md) for installation, clients, transports, signing, utilities, and guides. + ## Installation -**Bun 1.3.3+** +### Bun 1.3.3+ ```sh bun add @bloxwap/hyperliquid ``` -**Node.js 22.12+ / React Native 0.86+** +### Node.js 22.12+ / React Native 0.86+ ```sh npm i @bloxwap/hyperliquid ``` -**pnpm** +### pnpm ```sh pnpm add @bloxwap/hyperliquid ``` -**Yarn** +### Yarn ```sh yarn add @bloxwap/hyperliquid @@ -141,6 +145,7 @@ await subs.l2Book({ coin: "ETH" }, (data) => { ``` > [!WARNING] +> > - **Never hardcode private keys** in source or commit them to git. Load them from environment variables or a secret > store (Bun auto-loads a local `.env`, which is gitignored in this repo). > - For trading bots, prefer a Hyperliquid **agent wallet** (API wallet) over the master account key: an agent key can diff --git a/bun.lock b/bun.lock index 0b69385f..6ceca7df 100644 --- a/bun.lock +++ b/bun.lock @@ -17,6 +17,7 @@ "@valibot/to-json-schema": "1.7.1", "ajv": "8.20.0", "decimal.js": "10.6.0", + "markdownlint-cli2": "0.23.1", "ts-json-schema-generator": "2.9.0", "typescript": "5.9.3", "viem": "2.55.8", @@ -72,78 +73,248 @@ "@noble/hashes": ["@noble/hashes@2.2.0", "", {}, "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg=="], + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="], "@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="], "@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="], + "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="], + "@types/debug": ["@types/debug@4.1.13", "", { "dependencies": { "@types/ms": "*" } }, "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], + "@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + "@types/node": ["@types/node@26.1.1", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw=="], + "@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + "@valibot/to-json-schema": ["@valibot/to-json-schema@1.7.1", "", { "peerDependencies": { "valibot": "^1.4.0" } }, "sha512-3qkmU6KXWh8GIThEAW3kuRHPQBMjWkKy+Ppz3WkUucx53DTpOa6siMn4xDGSOhlVyMrDaJTCTMLYPZVAIk1P0A=="], "abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="], "ajv": ["ajv@8.20.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA=="], + "ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + + "argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], "brace-expansion": ["brace-expansion@5.0.8", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg=="], + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="], + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="], + "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="], + "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], + "decimal.js": ["decimal.js@10.6.0", "", {}, "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="], + "decode-named-character-reference": ["decode-named-character-reference@1.3.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="], "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + "fast-uri": ["fast-uri@3.1.4", "", {}, "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw=="], + "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="], + "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "globby": ["globby@16.2.1", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "fast-glob": "^3.3.3", "ignore": "^7.0.5", "is-path-inside": "^4.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.4.0" } }, "sha512-JmsqJalahxxgW8V2ecSQ2G7UjPlI9cpKdrkG9KoNiXhd/YslXOTEB0cViENWUznuovIuNT+FkMbraDGjr4FCUg=="], + "hash-wasm": ["hash-wasm@4.12.0", "", {}, "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ=="], + "ignore": ["ignore@7.0.6", "", {}, "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw=="], + + "is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="], + + "is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="], + + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-path-inside": ["is-path-inside@4.0.0", "", {}, "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA=="], + "isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="], + "js-yaml": ["js-yaml@5.2.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.mjs" } }, "sha512-zfLtNfQqxVqq3uaTqSkh4x4hZw3KHobGUA0fJUj4wawW8bsQLTVqpHdXSIzidh7o+4lEW36tANuAGdaFx6Zgnw=="], + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + "jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="], + + "jsonpointer": ["jsonpointer@5.0.1", "", {}, "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ=="], + + "katex": ["katex@0.16.47", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg=="], + + "linkify-it": ["linkify-it@5.0.2", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q=="], + "lru-cache": ["lru-cache@11.5.2", "", {}, "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g=="], + "markdown-it": ["markdown-it@14.3.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.5.0", "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw=="], + + "markdownlint": ["markdownlint@0.41.1", "", { "dependencies": { "micromark": "4.0.2", "micromark-core-commonmark": "2.0.3", "micromark-extension-directive": "4.0.0", "micromark-extension-gfm-autolink-literal": "2.1.0", "micromark-extension-gfm-footnote": "2.1.0", "micromark-extension-gfm-table": "2.1.1", "micromark-extension-math": "3.1.0", "micromark-util-types": "2.0.2", "string-width": "8.2.1" } }, "sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA=="], + + "markdownlint-cli2": ["markdownlint-cli2@0.23.1", "", { "dependencies": { "globby": "16.2.1", "js-yaml": "5.2.1", "jsonc-parser": "3.3.1", "jsonpointer": "5.0.1", "markdown-it": "14.3.0", "markdownlint": "0.41.1", "markdownlint-cli2-formatter-default": "0.0.6", "micromatch": "4.0.8", "smol-toml": "1.7.0" }, "bin": { "markdownlint-cli2": "markdownlint-cli2-bin.mjs" } }, "sha512-20JPI5W+HpV1OA+pUM712wgvL4GzYNUvbmhLU8KlEYJ1kCDx4soZ4/Xqd+WkLrPTOKMAn8SfO3zYFrK8GLlwQg=="], + + "markdownlint-cli2-formatter-default": ["markdownlint-cli2-formatter-default@0.0.6", "", { "peerDependencies": { "markdownlint-cli2": ">=0.0.4" } }, "sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ=="], + + "mdurl": ["mdurl@2.1.0", "", {}, "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="], + + "micromark-extension-directive": ["micromark-extension-directive@4.0.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "parse-entities": "^4.0.0" } }, "sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg=="], + + "micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="], + + "micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="], + + "micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="], + + "micromark-extension-math": ["micromark-extension-math@3.1.0", "", { "dependencies": { "@types/katex": "^0.16.0", "devlop": "^1.0.0", "katex": "^0.16.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg=="], + + "micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="], + + "micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + "minimatch": ["minimatch@10.2.5", "", { "dependencies": { "brace-expansion": "^5.0.5" } }, "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "ox": ["ox@0.14.32", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-EPB214GvtsP2TtAYZXkNdizLzGp6PXtfaHcRrD4pcBk/D0Y7ZCNv71QgwrjeCsZ+82moVeMlZZG+NDEIUfxMpw=="], + "parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="], + "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], + "picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], + + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="], + "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], + + "smol-toml": ["smol-toml@1.7.0", "", {}, "sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ=="], + + "string-width": ["string-width@8.2.1", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="], + + "strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="], + "tiny-secp256k1": ["tiny-secp256k1@2.2.4", "", { "dependencies": { "uint8array-tools": "0.0.7" } }, "sha512-FoDTcToPqZE454Q04hH9o2EhxWsm7pOSpicyHkgTwKhdKWdsTUuqfP5MLq3g+VjAtl2vSx6JpXGdwA2qpYkI0Q=="], + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + "ts-json-schema-generator": ["ts-json-schema-generator@2.9.0", "", { "dependencies": { "@types/json-schema": "^7.0.15", "commander": "^14.0.3", "glob": "^13.0.6", "json5": "^2.2.3", "normalize-path": "^3.0.0", "safe-stable-stringify": "^2.5.0", "tslib": "^2.8.1", "typescript": "^5.9.3" }, "bin": { "ts-json-schema-generator": "bin/ts-json-schema-generator.js" } }, "sha512-NR5ZE108uiPtBHBJNGnhwoUaUx5vWTDJzDFG9YlRoqxPU76n+5FClRh92dcGgysbe1smRmYalM9Saj97GW1J4Q=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], + "uint8array-tools": ["uint8array-tools@0.0.7", "", {}, "sha512-vrrNZJiusLWoFWBqz5Y5KMCgP9W9hnjZHzZiZRT8oNAkq3d5Z5Oe76jAvVVSRh4U8GGR90N2X1dWtrhvx6L8UQ=="], "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="], + "unicorn-magic": ["unicorn-magic@0.4.0", "", {}, "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw=="], + "valibot": ["valibot@1.4.2", "", { "peerDependencies": { "typescript": ">=5" }, "optionalPeers": ["typescript"] }, "sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg=="], "viem": ["viem@2.55.8", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.14.32", "ws": "8.21.0" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-BHqtsmK4iMLuLnRyrPIB1jVrmFVliRIP/K0dnFT7gBOpfo8Ko4ozhkzUCRNfR+Z/ZZdnlnVrh04fAOuIm5Svkg=="], @@ -156,6 +327,8 @@ "@scure/bip39/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], + "katex/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], + "ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], "viem/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="], diff --git a/docs/README.md b/docs/README.md index 4e6d425b..53444999 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,41 +1,42 @@ -# @bloxwap/hyperliquid +# @bloxwap/hyperliquid documentation -A community-supported [Hyperliquid API](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api) SDK for all -major JS runtimes, written in TypeScript. +`@bloxwap/hyperliquid` is a community-supported Hyperliquid API SDK for TypeScript and JavaScript runtimes. -## Installation +Use the [table of contents](SUMMARY.md) to browse every guide, or start with: + +- [Connect to Hyperliquid](transports.md) +- [Clients](clients.md) +- [Error handling](error-handling.md) +- [Utilities](utilities.md) +- [Signing](signing.md) -{% tabs %} +## Installation -{% tab title="Bun 1.3.3+" %} +### Bun 1.3.3+ ```sh bun add @bloxwap/hyperliquid ``` -{% endtab %} - -{% tab title="Node.js 22.12+" %} +### Node.js 22.12+ ```sh npm i @bloxwap/hyperliquid ``` -{% endtab %} - -{% tab title="pnpm / yarn" %} +### pnpm ```sh pnpm add @bloxwap/hyperliquid ``` +### Yarn + ```sh yarn add @bloxwap/hyperliquid ``` -{% endtab %} - -{% tab title="React Native 0.86+" %} +### React Native 0.86+ ```sh npm i @bloxwap/hyperliquid @@ -54,7 +55,7 @@ import "web-streams-polyfill/polyfill"; import "compression-streams-polyfill"; ``` -On **React Native < 0.86** the global `Event`/`EventTarget` is missing — polyfill it: +On **React Native < 0.86**, the global `Event` and `EventTarget` are missing: ```sh npm i event-target-shim @@ -62,11 +63,12 @@ npm i event-target-shim ```ts import { Event, EventTarget } from "event-target-shim"; + if (!globalThis.EventTarget) globalThis.EventTarget = EventTarget; if (!globalThis.Event) globalThis.Event = Event; ``` -On **React Native < 0.84** the native `URL` is incomplete — add `react-native-url-polyfill`: +On **React Native < 0.84**, the native `URL` is incomplete: ```sh npm i react-native-url-polyfill @@ -76,19 +78,14 @@ npm i react-native-url-polyfill import "react-native-url-polyfill/auto"; ``` -Import every polyfill before `@bloxwap/hyperliquid` (e.g. at the top of `index.js`). - -{% endtab %} - -{% endtabs %} +Import every polyfill before `@bloxwap/hyperliquid`, such as at the top of `index.js`. ## Quick start -{% tabs %} - -{% tab title="InfoClient" %} +### Read market data -Read market data, account state, order book. [Learn more](clients.md#info-endpoint) +Use `InfoClient` to read market data, account state, and order books. See the [Info endpoint](clients.md#info-endpoint) +for all client behavior. ```ts import { HttpTransport, InfoClient } from "@bloxwap/hyperliquid"; @@ -99,18 +96,16 @@ const client = new InfoClient({ transport }); const mids = await client.allMids(); ``` -{% endtab %} +### Trade -{% tab title="ExchangeClient" %} - -Place orders, transfer funds, manage accounts. [Learn more](clients.md#exchange-endpoint) +Use `ExchangeClient` to place orders, transfer funds, and manage accounts. See the +[Exchange endpoint](clients.md#exchange-endpoint) before using a funded wallet. ```ts import { ExchangeClient, HttpTransport } from "@bloxwap/hyperliquid"; import { privateKeyToAccount } from "viem/accounts"; const wallet = privateKeyToAccount("0x..."); - const transport = new HttpTransport(); const client = new ExchangeClient({ transport, wallet }); @@ -127,11 +122,10 @@ await client.order({ }); ``` -{% endtab %} +### Subscribe -{% tab title="SubscriptionClient" %} - -Receive real-time updates via WebSocket. [Learn more](clients.md#websocket-subscriptions) +Use `SubscriptionClient` to receive real-time updates. See +[WebSocket subscriptions](clients.md#websocket-subscriptions) for subscription lifecycle details. ```ts import { SubscriptionClient, WebSocketTransport } from "@bloxwap/hyperliquid"; @@ -144,11 +138,10 @@ await client.allMids((data) => { }); ``` -{% endtab %} - -{% tab title="ExplorerClient" %} +### Explore -Look up blocks, transactions, and addresses. [Learn more](clients.md#explorer-endpoint) +Use `ExplorerClient` to look up blocks, transactions, and addresses. See the +[Explorer endpoint](clients.md#explorer-endpoint) for the available methods. ```ts import { ExplorerClient, HttpTransport } from "@bloxwap/hyperliquid"; @@ -159,19 +152,15 @@ const client = new ExplorerClient({ transport }); const block = await client.blockDetails({ height: 123 }); ``` -{% endtab %} - -{% endtabs %} - ## Versioning This SDK follows [Semantic Versioning](https://semver.org/). Until `1.0.0`, breaking changes bump the minor version and -everything else bumps the patch — the [caret-range](https://github.com/npm/node-semver#caret-ranges-123-025-004) -convention. +everything else bumps the patch, following the +[caret-range convention](https://github.com/npm/node-semver#caret-ranges-123-025-004). -The exception is the request, response, and event types that mirror the Hyperliquid API. The API is unversioned and -always serves its latest shape, so changes to these types ship in **patch** releases even when breaking — the break -comes from Hyperliquid, not the SDK. +The exception is request, response, and event types that mirror the Hyperliquid API. The API is unversioned and always +serves its latest shape, so changes to these types ship in patch releases even when breaking: the break comes from +Hyperliquid, not the SDK. -For places where the official Hyperliquid docs and the live API currently disagree — and what this SDK does about -each — see [Known documentation drift](reference/known-drift.md). +For places where the official Hyperliquid documentation and the live API currently disagree, see +[Known documentation drift](reference/known-drift.md). diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 9f15ef58..82760dee 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -1,6 +1,8 @@ -# Table of contents +# Documentation -- [Introduction](README.md) +## Core concepts + +- [Introduction and installation](README.md) - [Connect to Hyperliquid](transports.md) - [Clients](clients.md) - [Error handling](error-handling.md) @@ -17,1839 +19,3 @@ ## Reference - [Known documentation drift](reference/known-drift.md) - -## API Reference - -- Info Methods - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-activeAssetData - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-allBorrowLendReserveStates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-allMids - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-allPerpMetas - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-approvedBuilders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-borrowLendReserveState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-borrowLendUserState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-candleSnapshot - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-clearinghouseState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-delegations - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-delegatorHistory - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-delegatorRewards - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-delegatorSummary - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-exchangeStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-extraAgents - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-frontendOpenOrders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-fundingHistory - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-gossipPriorityAuctionStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-gossipRootIps - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-historicalOrders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-isVip - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-l2Book - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-leadingVaults - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-legalCheck - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-liquidatable - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-marginTable - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-maxBuilderFee - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-maxMarketOrderNtls - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-meta - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-metaAndAssetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-openOrders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-orderStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-outcomeMeta - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpAnnotation - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpCategories - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpConciseAnnotations - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpDeployAuctionStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpDexLimits - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpDexStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpDexs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-perpsAtOpenInterestCap - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-portfolio - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-preTransferCheck - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-predictedFundings - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-recentTrades - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-referral - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-settledOutcome - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-spotClearinghouseState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-spotDeployState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-spotMeta - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-spotMetaAndAssetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-spotPairDeployAuctionStatus - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-subAccounts - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-subAccounts2 - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-tokenDetails - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-twapHistory - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userBorrowLendInterest - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userDexAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userFees - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userFills - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userFillsByTime - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userFunding - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userNonFundingLedgerUpdates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userRateLimit - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userRole - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userToMultiSigSigners - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userTwapSliceFills - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userTwapSliceFillsByTime - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-userVaultEquities - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-validatorL1Votes - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-validatorSummaries - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-vaultDetails - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-vaultSummaries - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-info-webData2 - ``` - -- Exchange Methods - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-agentEnableDexAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-agentSendAsset - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-agentSetAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-approveAgent - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-approveBuilderFee - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-authorizeAqav2Role - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-batchModify - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-borrowLend - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cDeposit - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cSignerAction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cValidatorAction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cWithdraw - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cancel - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-cancelByCloid - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-claimRewards - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-convertToMultiSigUser - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-createSubAccount - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-createVault - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-evmUserModify - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-finalizeEvmContract - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-gossipPriorityBid - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-hip3LiquidatorTransfer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-linkStakingUser - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-modify - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-noop - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-order - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-perpDeploy - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-registerReferrer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-reserveRequestWeight - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-scheduleCancel - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-sendAsset - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-sendToEvmWithData - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-setDisplayName - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-setReferrer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-spotDeploy - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-spotSend - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-spotUser - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-stakingLinkDisableTradingUser - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-subAccountModify - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-subAccountSpotTransfer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-subAccountTransfer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-tokenDelegate - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-topUpIsolatedOnlyMargin - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-twapCancel - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-twapOrder - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-updateIsolatedMargin - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-updateLeverage - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-usdClassTransfer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-usdSend - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-userDexAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-userOutcome - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-userPortfolioMargin - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-userSetAbstraction - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-validatorL1Stream - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-vaultDistribute - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-vaultModify - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-vaultTransfer - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-exchange-withdraw3 - ``` - -- Subscription Methods - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-activeAssetCtx - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-activeAssetData - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-activeSpotAssetCtx - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-allDexsAssetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-allDexsClearinghouseState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-allMids - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-assetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-bbo - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-candle - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-clearinghouseState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-fastAssetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-l2Book - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-notification - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-openOrders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-orderUpdates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-outcomeMetaUpdates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-spotAssetCtxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-spotState - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-trades - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-twapStates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userEvents - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userFills - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userFundings - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userHistoricalOrders - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userNonFundingLedgerUpdates - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userTwapHistory - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-userTwapSliceFills - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-subscription-webData3 - ``` - -- Explorer Methods - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-explorer-blockDetails - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-explorer-explorerBlock - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-explorer-explorerTxs - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-explorer-txDetails - ``` - - ```yaml - type: builtin:openapi - props: - models: false - downloadLink: false - dependencies: - spec: - ref: - kind: openapi - spec: hl-explorer-userDetails - ``` diff --git a/docs/clients.md b/docs/clients.md index 91859492..873c964a 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -54,9 +54,8 @@ pages. `ExchangeClient` requires a wallet for [signing](signing.md#wallet-compatibility) and works with any transport. See all [Exchange methods](https://nktkas.gitbook.io/hyperliquid/api-reference/exchange-methods). -{% tabs %} - -{% tab title="viem" %} +
+viem ```ts import { ExchangeClient, HttpTransport } from "@bloxwap/hyperliquid"; @@ -70,9 +69,10 @@ const client = new ExchangeClient({ transport, wallet }); await client.order({ orders: [/* ... */], grouping: "na" }); ``` -{% endtab %} +
-{% tab title="Browser (viem)" %} +
+Browser (viem) ```ts import { ExchangeClient, HttpTransport } from "@bloxwap/hyperliquid"; @@ -88,9 +88,10 @@ const client = new ExchangeClient({ transport, wallet }); await client.order({ orders: [/* ... */], grouping: "na" }); ``` -{% endtab %} +
-{% tab title="Custom" %} +
+Custom Any object matching one of the [supported wallet interfaces](signing.md#wallet-compatibility) works. The minimum requirement is [`signTypedData`](https://eips.ethereum.org/EIPS/eip-712) and an `address`: @@ -113,9 +114,7 @@ const client = new ExchangeClient({ transport, wallet }); await client.order({ orders: [/* ... */], grouping: "na" }); ``` -{% endtab %} - -{% endtabs %} +
### Multi-sig @@ -231,15 +230,13 @@ const client = new ExchangeClient({ }); ``` -{% hint style="warning" %} - -A custom `nonceManager` MUST return unique, monotonically increasing values per address — a plain -`(address) => Date.now()` reintroduces same-millisecond collisions, and Hyperliquid only tracks the 100 highest -nonces per user (rejecting repeats and anything outside that window). When more than one process signs for the same -wallet, back the manager with shared state (e.g. Redis). See -[Operational nonce rules](signing.md#operational-nonce-rules). - -{% endhint %} +> [!WARNING] +> +> A custom `nonceManager` MUST return unique, monotonically increasing values per address — a plain +> `(address) => Date.now()` reintroduces same-millisecond collisions, and Hyperliquid only tracks the 100 highest +> nonces per user (rejecting repeats and anything outside that window). When more than one process signs for the same +> wallet, back the manager with shared state (e.g. Redis). See +> [Operational nonce rules](signing.md#operational-nonce-rules). ### Pre-signed payloads (sign now, submit later) @@ -279,14 +276,12 @@ Beyond callback settle, enforcement is **best-effort**: rejection by definition. The rejection is delivered to the attempt's own promise; observing it is the leaker's responsibility, not something the SDK can prevent. -{% hint style="warning" %} - -The nonce is consumed at **prepare** time. The exchange tracks the 100 highest nonces per user: a prepared payload -stays valid while its nonce is among them (and within the block-timestamp window) — another request consuming a -later nonce does NOT invalidate it. The payload goes **stale** only once 100 newer nonces have been consumed. -Prepare immediately before use anyway. - -{% endhint %} +> [!WARNING] +> +> The nonce is consumed at **prepare** time. The exchange tracks the 100 highest nonces per user: a prepared payload +> stays valid while its nonce is among them (and within the block-timestamp window) — another request consuming a +> later nonce does NOT invalidate it. The payload goes **stale** only once 100 newer nonces have been consumed. +> Prepare immediately before use anyway. ### Orders over WebSocket (low latency) @@ -315,16 +310,14 @@ const client = new ExchangeClient({ transport, wallet }); await client.order({ orders: [/* ... */], grouping: "na" }); ``` -{% hint style="warning" %} - -The server allows at most -[100 simultaneous in-flight post messages](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits) -across all WebSocket connections per IP (plus 2000 messages/minute overall) — the cap counts concurrent requests, not -requests per minute, so with typical round trips it sustains far more than the HTTP per-minute budget. An over-limit -post is rejected and the affected call throws `WebSocketRequestError` ("too many pending post requests"). Leave -headroom when several clients share the connection or the IP runs several connections. - -{% endhint %} +> [!WARNING] +> +> The server allows at most +> [100 simultaneous in-flight post messages](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits) +> across all WebSocket connections per IP (plus 2000 messages/minute overall) — the cap counts concurrent requests, not +> requests per minute, so with typical round trips it sustains far more than the HTTP per-minute budget. An over-limit +> post is rejected and the affected call throws `WebSocketRequestError` ("too many pending post requests"). Leave +> headroom when several clients share the connection or the IP runs several connections. Two more caveats: explorer requests are HTTP-only, so keep an `HttpTransport` around if you use [`ExplorerClient`](#explorer-endpoint); and WS requests are bounded by the transport-wide `timeout` — the HTTP-only @@ -508,18 +501,16 @@ await client.order({ orders: [/* ... */], grouping: "na" }, { }); ``` -{% hint style="danger" %} - -**Unsafe for untrusted input.** On this path the SDK performs no validation, normalization, default-filling, or key -reordering — parameters are signed and posted exactly as given, so they must already be in canonical wire form: - -- object keys in schema-declared order (the signature commits to the encoded key order); -- decimals as normalized strings (e.g. `"30000"`, not `3e4` or `"030000"`); -- addresses and hex strings in lowercase; -- every schema field with a default (e.g. `grouping: "na"`) provided explicitly. - -Invalid input is the caller's problem: instead of a client-side `ValidationError`, the server rejects the request — -detecting that drift is the cost of the saved microseconds. Cheap deterministic guards for documented constraints -(e.g. `scheduleCancel`'s 5-second lead time) still run. - -{% endhint %} +> [!CAUTION] +> +> **Unsafe for untrusted input.** On this path the SDK performs no validation, normalization, default-filling, or key +> reordering — parameters are signed and posted exactly as given, so they must already be in canonical wire form: +> +> - object keys in schema-declared order (the signature commits to the encoded key order); +> - decimals as normalized strings (e.g. `"30000"`, not `3e4` or `"030000"`); +> - addresses and hex strings in lowercase; +> - every schema field with a default (e.g. `grouping: "na"`) provided explicitly. +> +> Invalid input is the caller's problem: instead of a client-side `ValidationError`, the server rejects the request — +> detecting that drift is the cost of the saved microseconds. Cheap deterministic guards for documented constraints +> (e.g. `scheduleCancel`'s 5-second lead time) still run. diff --git a/docs/error-handling.md b/docs/error-handling.md index d3f860da..7bbc5048 100644 --- a/docs/error-handling.md +++ b/docs/error-handling.md @@ -7,7 +7,7 @@ Typed exceptions thrown by `@bloxwap/hyperliquid` so you can route error handlin Every exception the SDK itself throws extends `HyperliquidError`. One `instanceof` check is enough to separate "something in the SDK threw" from "something else threw". -``` +```text Error └─ HyperliquidError ├─ ValidationError diff --git a/docs/signing.md b/docs/signing.md index 2b305da3..a77fa930 100644 --- a/docs/signing.md +++ b/docs/signing.md @@ -87,9 +87,8 @@ Three optional parameters: - `vaultAddress` — sign through a vault; folded into the hash. - `expiresAfter` — reject the action after this timestamp; folded into the hash. -{% tabs %} - -{% tab title="viem" %} +
+viem ```ts import { signL1Action } from "@bloxwap/hyperliquid/signing"; @@ -109,9 +108,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Browser (viem)" %} +
+Browser (viem) ```ts import { signL1Action } from "@bloxwap/hyperliquid/signing"; @@ -133,9 +133,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Custom" %} +
+Custom ```ts import { signL1Action } from "@bloxwap/hyperliquid/signing"; @@ -161,9 +162,7 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} - -{% endtabs %} +
## User-signed actions @@ -174,9 +173,8 @@ Each action type has its own types, exported from `@bloxwap/hyperliquid/api/exch `PascalCase(actionType) + "Types"` — `ApproveAgentTypes` for `approveAgent`, `Withdraw3Types` for `withdraw3`, and so on. -{% tabs %} - -{% tab title="viem" %} +
+viem ```ts import { signUserSignedAction } from "@bloxwap/hyperliquid/signing"; @@ -203,9 +201,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Browser (viem)" %} +
+Browser (viem) ```ts import { signUserSignedAction } from "@bloxwap/hyperliquid/signing"; @@ -234,9 +233,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Custom" %} +
+Custom ```ts import { signUserSignedAction } from "@bloxwap/hyperliquid/signing"; @@ -269,9 +269,7 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} - -{% endtabs %} +
## Action hashing @@ -288,12 +286,10 @@ const hash = createL1ActionHash({ }); ``` -{% hint style="warning" %} - -The hash depends on key order in the action object. The expected order varies by action type — look it up in that -action's valibot schema (e.g., `CancelRequest` for `cancel`), or hand the action to [`canonicalize`](#canonicalize). - -{% endhint %} +> [!WARNING] +> +> The hash depends on key order in the action object. The expected order varies by action type — look it up in that +> action's valibot schema (e.g., `CancelRequest` for `cancel`), or hand the action to [`canonicalize`](#canonicalize). ## Canonicalize @@ -330,9 +326,8 @@ It returns `{ action, signature }`, where `action` is the multi-sig wrapper — Optional `isTestnet`, `vaultAddress`, and `expiresAfter` behave as in [`signL1Action`](#l1-actions). -{% tabs %} - -{% tab title="viem" %} +
+viem ```ts import { signMultiSigL1 } from "@bloxwap/hyperliquid/signing"; @@ -362,9 +357,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Browser (viem)" %} +
+Browser (viem) ```ts import { signMultiSigL1 } from "@bloxwap/hyperliquid/signing"; @@ -399,9 +395,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Custom" %} +
+Custom ```ts import { signMultiSigL1 } from "@bloxwap/hyperliquid/signing"; @@ -436,9 +433,7 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} - -{% endtabs %} +
### signMultiSigUserSigned @@ -448,9 +443,8 @@ pass the same `types` as the single-signer call. It returns `{ action, signature }` — `action` is the wrapper to send, not your original action. -{% tabs %} - -{% tab title="viem" %} +
+viem ```ts import { signMultiSigUserSigned } from "@bloxwap/hyperliquid/signing"; @@ -486,9 +480,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Browser (viem)" %} +
+Browser (viem) ```ts import { signMultiSigUserSigned } from "@bloxwap/hyperliquid/signing"; @@ -530,9 +525,10 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} +
-{% tab title="Custom" %} +
+Custom ```ts import { signMultiSigUserSigned } from "@bloxwap/hyperliquid/signing"; @@ -572,9 +568,7 @@ await fetch("https://api.hyperliquid.xyz/exchange", { }); ``` -{% endtab %} - -{% endtabs %} +
## Wallet compatibility diff --git a/docs/transports.md b/docs/transports.md index acf655be..c6903bbb 100644 --- a/docs/transports.md +++ b/docs/transports.md @@ -42,7 +42,7 @@ const exchange = new ExchangeClient({ wallet, transport }); const mids = await info.allMids(); ``` -### Endpoints +### HTTP endpoints `HttpTransport` uses two endpoints, both defaulting to Hyperliquid's public URLs (set `isTestnet` to send requests to the testnet URL): @@ -173,7 +173,7 @@ await subs.allMids((data) => { // Promise is resolved when the subscription is connected ``` -### Endpoints +### WebSocket endpoints Because a WebSocket transport is one open connection, it reaches a single endpoint per instance, unlike `HttpTransport`. `WebSocketTransport` therefore takes one `url` (default `wss://api.hyperliquid.xyz/ws`) for info, exchange, and @@ -253,5 +253,5 @@ by hand. Delivery pauses while the connection is down and resumes once it's back const transport = new WebSocketTransport({ resubscribe: false }); ``` -If a subscription then fails to re-establish, its `onError` callback is invoked — handle it as shown in -[Handle failures](#handle-failures). +If a subscription then fails to re-establish, its `onError` callback is invoked. Handle it as shown under +[subscription errors](clients.md#errors). diff --git a/docs/utilities.md b/docs/utilities.md index 01928ba7..fb46c4d3 100644 --- a/docs/utilities.md +++ b/docs/utilities.md @@ -34,21 +34,17 @@ formatPrice("0.0000123456789", 0, "spot"); // "0.00001234" — spot, 8-decimal The third argument selects the market type and defaults to `"perp"`. Pass `"spot"` when the price belongs to a spot market — the decimal ceiling differs. -{% hint style="info" %} - -Don't rely on -[`toFixed(n)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed): it -rounds instead of truncating, ignores the significant-figures ceiling and has issues with -[floating-point precision](https://floating-point-gui.de/). - -{% endhint %} - -{% hint style="warning" %} - -`formatPrice` **truncates**, it does not round. If truncation collapses a very small price to `0`, it throws -`FormatError`. - -{% endhint %} +> [!NOTE] +> +> Don't rely on +> [`toFixed(n)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed): it +> rounds instead of truncating, ignores the significant-figures ceiling and has issues with +> [floating-point precision](https://floating-point-gui.de/). + +> [!WARNING] +> +> `formatPrice` **truncates**, it does not round. If truncation collapses a very small price to `0`, it throws +> `FormatError`. @@ -65,13 +61,11 @@ formatSize("0.123456789", 2); // "0.12" formatSize("100", 0); // "100" ``` -{% hint style="warning" %} - -Hyperliquid treats a literal `"0"` size on a reduce-only order as "close the whole position". `formatSize` refuses to -return `"0"` (it throws `FormatError`), so if you actually want that behavior, pass `"0"` directly into the order -payload instead of routing it through `formatSize`. - -{% endhint %} +> [!WARNING] +> +> Hyperliquid treats a literal `"0"` size on a reduce-only order as "close the whole position". `formatSize` refuses to +> return `"0"` (it throws `FormatError`), so if you actually want that behavior, pass `"0"` directly into the order +> payload instead of routing it through `formatSize`. @@ -249,9 +243,8 @@ await converter.reload(); [HIP-3 builder-deployed perpetuals](https://hyperliquid.gitbook.io/hyperliquid-docs/hyperliquid-improvement-proposals-hips/hip-3-builder-deployed-perpetuals) live outside the default universe. `SymbolConverter` ignores them unless you opt in through the `dexs` option: -{% tabs %} - -{% tab title="All builder DEXs" %} +
+All builder DEXs ```ts const converter = await SymbolConverter.create({ @@ -260,9 +253,10 @@ const converter = await SymbolConverter.create({ }); ``` -{% endtab %} +
-{% tab title="Selected DEXs" %} +
+Selected DEXs ```ts const converter = await SymbolConverter.create({ @@ -271,9 +265,7 @@ const converter = await SymbolConverter.create({ }); ``` -{% endtab %} - -{% endtabs %} +
Builder DEX assets use the `"DEX:ASSET"` naming convention: @@ -282,13 +274,11 @@ converter.getAssetId("test:ABC"); // 110000 converter.getSzDecimals("test:ABC"); // 0 ``` -{% hint style="info" %} - -Enabling `dexs` adds a `perpDexs()` call plus one `meta({ dex })` request per builder DEX. Only enable it if you -actually trade there — the default `SymbolConverter.create()` is one round-trip each to `meta`, `spotMeta`, and -`outcomeMeta` in parallel. - -{% endhint %} +> [!NOTE] +> +> Enabling `dexs` adds a `perpDexs()` call plus one `meta({ dex })` request per builder DEX. Only enable it if you +> actually trade there — the default `SymbolConverter.create()` is one round-trip each to `meta`, `spotMeta`, and +> `outcomeMeta` in parallel. ## End-to-end: resolve, format, place diff --git a/package.json b/package.json index b832c74a..4f388962 100644 --- a/package.json +++ b/package.json @@ -42,9 +42,11 @@ }, "scripts": { "//check": "Everything CI gates on.", - "check": "bun run check:format && bun run check:lint && bun run check:types && bun run check:ts7 && bun run check:jsdoc && bun run check:export", + "check": "bun run check:format && bun run check:lint && bun run check:docs && bun run check:types && bun run check:ts7 && bun run check:jsdoc && bun run check:export", "check:format": "biome format .", "check:lint": "biome lint .", + "//check:docs": "Verifies Markdown formatting, the docs index, and GitHub-compatible syntax. External links are checked by the Documentation workflow.", + "check:docs": "bun run .dev/docs_check.ts && markdownlint-cli2 \"README.md\" \"docs/**/*.md\"", "//check:types": "TypeScript 5 pass over sources and tests (the version the JS-API tooling pins).", "check:types": "tsc --project tsconfig.json", "//check:ts7": "Forward-compatibility gate: TypeScript 7 (native) over src/. See .dev/ts7/tsconfig.json.", @@ -83,6 +85,7 @@ "@valibot/to-json-schema": "1.7.1", "ajv": "8.20.0", "decimal.js": "10.6.0", + "markdownlint-cli2": "0.23.1", "ts-json-schema-generator": "2.9.0", "typescript": "5.9.3", "viem": "2.55.8" diff --git a/tsconfig.json b/tsconfig.json index 41947de7..f4827adc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,5 +17,5 @@ "skipLibCheck": true }, "include": ["src/**/*.ts", "tests/**/*.ts", ".dev/**/*.ts"], - "exclude": [".dev/ts7", "node_modules", "dist"] + "exclude": [".dev/ts7", ".dev/worktrees", "node_modules", "dist"] }